PHP Doku:: Zerlegt eine Zeichenkette anhand eines regulären Ausdrucks - function.preg-split.html

Verlauf / Chronik / History: (1) anzeigen

Sie sind hier:
Doku-StartseitePHP-HandbuchFunktionsreferenzTextverarbeitungReguläre Ausdrücke (Perl-kompatibel)PCRE-Funktionenpreg_split

Ein Service von Reinhard Neidl - Webprogrammierung.

PCRE-Funktionen

<<preg_replace

Reguläre Ausdrücke (POSIX-erweitert)>>

preg_split

(PHP 4, PHP 5)

preg_splitZerlegt eine Zeichenkette anhand eines regulären Ausdrucks

Beschreibung

array preg_split ( string $pattern , string $subject [, int $limit = -1 [, int $flags = 0 ]] )

Zerlegt die angegebene Zeichenkette anhand eines regulären Ausdrucks.

Parameter-Liste

pattern

Der Ausdruck, nach dem gesucht werden soll, als Zeichenkette.

subject

Die zu zerlegende Zeichenkette.

limit

Falls angegeben, werden maximal limit Teilzeichenketten zurückgegeben, wobei der Rest der Zeichenkette in der letzten Teilzeichenkette abgelegt wird. Ein limit von -1, 0 oder Null bedeutet "kein Limit" und wie es in PHP Standard ist, kann Null verwendet werden um den Parameter flags zu überspringen.

flags

flags kann jede Kombination der folgenden Flags sein (verknüpft mit dem bitweisen | Operator):

PREG_SPLIT_NO_EMPTY
Falls dieses Flag gesetzt ist, werden von preg_split() nur die Teile zurückgegeben, die nicht leer sind.
PREG_SPLIT_DELIM_CAPTURE
Falls dieses Flag gesetzt ist, werden auch die eingeklammerten Ausdrücke des Trennsymbol-Suchmusters erfasst und zurückgegeben.
PREG_SPLIT_OFFSET_CAPTURE

Falls dieses Flag gesetzt ist, wird mit jeder gefundenen Übereinstimmung der dazugehörige Versatz in der Zeichenkette zurückgegeben. Beachten Sie, dass dies die Rückgabewerte in einem Array dahingehend ändert, dass jedes Element ein Array ist, das aus der übereinstimmenden Zeichenkette als Element 0 und deren Stelle in subject als Element 1 besteht.

Rückgabewerte

Gibt ein Array zurück, bestehend aus Teilzeichenketten der Zeichenkette subject, die an den auf das Suchmuster pattern passenden Stellen zerlegt wurde.

Changelog

Version Beschreibung
4.3.0 Das Flag PREG_SPLIT_OFFSET_CAPTURE hinzugefügt
4.0.5 Das Flag PREG_SPLIT_DELIM_CAPTURE hinzugefügt

Beispiele

Beispiel #1 preg_split() Beispiel: Eine Zeichenkette in ihre Bestandteile zerlegen

<?php
// zerlegt die Zeichenkette an Stellen mit beliebiger Anzahl von
// Kommata oder Leerzeichen, die " ", \r, \t, \n und \f umfassen
$schluesselwoerter preg_split("/[\s,]+/""hypertext language, programming");
?>

Beispiel #2 Eine Zeichenkette in einzelne Zeichen zerlegen

<?php
$str 
'Zeichenkette';
$zeichen preg_split('//'$str, -1PREG_SPLIT_NO_EMPTY);
print_r($zeichen);
?>

Beispiel #3 Eine Zeichenkette in Übereinstimmungen mit dem Suchmuster und deren Versatz zerlegen

<?php
$str 
'hypertext language programming';
$zeichen preg_split('/ /'$str, -1PREG_SPLIT_OFFSET_CAPTURE);
print_r($zeichen);
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

Array
(
    [0] => Array
        (
            [0] => hypertext
            [1] => 0
        )

    [1] => Array
        (
            [0] => language
            [1] => 10
        )

    [2] => Array
        (
            [0] => programming
            [1] => 19
        )

)

Anmerkungen

Tipp

Falls Sie die Leistung regulärer Ausdrücke nicht benötigen, können Sie stattdessen schnellere (wenngleich einfachere) Alternativen wie explode() oder str_split() verwenden.

Siehe auch

  • implode() - Verbindet Array-Elemente zu einem String
  • preg_match() - Führt eine Suche mit einem regulären Ausdruck durch
  • preg_match_all() - Führt eine umfassende Suche nach Übereinstimmungen mit regulärem Ausdruck durch
  • preg_replace() - Sucht und ersetzt mit regulären Ausdrücken
  • preg_last_error() - Liefert den Fehlercode der letzten PCRE RegEx-Auswertung


19 BenutzerBeiträge:
- Beiträge aktualisieren...
PhoneixSegovia at gmail dot com
26.11.2010 13:38
You must be caution when using lookbehind to a variable match.
For example:
'/(?<!\\\)\r?\n)/'
 to match a new line when not \ is before it don't go as spected as it match \r as the lookbehind (becouse isn't a \) and is optional before \n.

You must use this for example:
'/((?<!\\\|\r)\n)|((?<!\\\)\r\n)/'
That match a alone \n (not preceded by \r or \) or a \r\n not preceded by a \.
Daniel Schroeder
3.11.2010 12:46
If you want to split by a char, but want to ignore that char in case it is escaped, use a lookbehind assertion.

In this example a string will be split by ":" but "\:" will be ignored:

<?php
$string
='a:b:c\:d';
$array=preg_split('#(?<!\\\)\:#',$string);
print_r($array);
?>

Results into:

Array
(
    [0] => a
    [1] => b
    [2] => c\:d
)
sergei dot garrison at gmail dot com
5.03.2010 17:04
If you need to split a list of "tags" while allowing for user error, you'll find this more useful than the manual's first example.

<?php
$string
= 'one, two,three,     four  , five,six seven';
$array = preg_split("/[\s]*[,][\s]*/", $string);
print_r($array);
// Array ( [0] => one [1] => two [2] => three [3] => four [4] => five [5] => six seven )
?>

This splits the string *only* by commas, regardless of how many spaces there are on either side of any comma.
nesbert at gmail dot com
29.01.2010 0:46
Hope this helps someone...

<?php
/**
 * Split a string into groups of words with a line no longer than $max
 * characters.
 *
 * @param string $string
 * @param integer $max
 * @return array
 **/
function split_words($string, $max = 1)
{
   
$words = preg_split('/\s/', $string);
   
$lines = array();
   
$line = '';
   
    foreach (
$words as $k => $word) {
       
$length = strlen($line . ' ' . $word);
        if (
$length <= $max) {
           
$line .= ' ' . $word;
        } else if (
$length > $max) {
            if (!empty(
$line)) $lines[] = trim($line);
           
$line = $word;
        } else {
           
$lines[] = trim($line) . ' ' . $word;
           
$line = '';
        }
    }
   
$lines[] = ($line = trim($line)) ? $line : $word;

    return
$lines;
}
?>
jan dot sochor at icebolt dot info
24.10.2009 12:26
Sometimes PREG_SPLIT_DELIM_CAPTURE does strange results.

<?php
$content
= '<strong>Lorem ipsum dolor</strong> sit <img src="test.png" />amet <span class="test" style="color:red">consec<i>tet</i>uer</span>.';
$chars = preg_split('/<[^>]*[^\/]>/i', $content, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
print_r($chars);
?>
Produces:
Array
(
    [0] => Lorem ipsum dolor
    [1] =>  sit <img src="test.png" />amet
    [2] => consec
    [3] => tet
    [4] => uer
)

So that the delimiter patterns are missing. If you wanna get these patters remember to use parentheses.

<?php
$chars
= preg_split('/(<[^>]*[^\/]>)/i', $content, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
print_r($chars); //parentheses added
?>
Produces:
Array
(
    [0] => <strong>
    [1] => Lorem ipsum dolor
    [2] => </strong>
    [3] =>  sit <img src="test.png" />amet
    [4] => <span class="test" style="color:red">
    [5] => consec
    [6] => <i>
    [7] => tet
    [8] => </i>
    [9] => uer
    [10] => </span>
    [11] => .
)
php at dmi dot me dot uk
6.10.2009 10:23
To split a camel-cased string using preg_split() with lookaheads and lookbehinds:

<?php
function splitCamelCase($str) {
  return
preg_split('/(?<=\\w)(?=[A-Z])/', $str);
}
?>
Peter -the pete- de Pijd
24.09.2009 11:34
If you want to use something like explode(PHP_EOL, $string) but for all combinations of \r and \n, try this one:

<?php
$text
= "A\nB\rC\r\nD\r\rE\n\nF";
$texts = preg_split("/((\r(?!\n))|((?<!\r)\n)|(\r\n))/", $text);
?>

result:
array("A", "B", "C", "D", "", "E", "", "F");
buzoganylaszlo at yahoo dot com
1.08.2009 9:57
Extending m.timmermans's solution, you can use the following code as a search expression parser:

<?php
$search_expression
= "apple bear \"Tom Cruise\" or 'Mickey Mouse' another word";
$words = preg_split("/[\s,]*\\\"([^\\\"]+)\\\"[\s,]*|" . "[\s,]*'([^']+)'[\s,]*|" . "[\s,]+/", $search_expression, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
print_r($words);
?>

The result will be:
Array
(
    [0] => apple
    [1] => bear
    [2] => Tom Cruise
    [3] => or
    [4] => Mickey Mouse
    [5] => another
    [6] => word
)

1. Accepted delimiters: white spaces (space, tab, new line etc.) and commas.

2. You can use either simple (') or double (") quotes for expressions which contains more than one word.
wf
28.05.2009 18:36
Spacing out your CamelCase using preg_replace:

<?php

function spacify($camel, $glue = ' ') {
    return
preg_replace( '/([a-z0-9])([A-Z])/', "$1$glue$2", $camel );
}

echo
spacify('CamelCaseWords'), "\n"; // 'Camel Case Words'
echo spacify('camelCaseWords'), "\n"; // 'camel Case Words'

?>
chris AT cmbuckley DOT co DOT uk
27.05.2009 12:11
Here's a helpful function to space out your CamelCase using preg_split:

<?php

function spacify($camel, $glue = ' ') {
    return
$camel[0] . substr(implode($glue, array_map('implode', array_chunk(preg_split('/([A-Z])/',
       
ucfirst($camel), -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE), 2))), 1);
}

echo
spacify('CamelCaseWords'); // 'Camel Case Words'
echo spacify('camelCaseWords'); // 'camel Case Words'

?>
kenorb at gmail dot com
23.05.2009 16:56
If you need convert function arguments without default default values and references, you can try this code:

<?php
    $func_args
= '$node, $op, $a3 = NULL, $form = array(), $a4 = NULL'
   
$call_arg = preg_match_all('@(?<func_arg>\$[^,= ]+)@i', $func_args, $matches);
   
$call_arg = implode(',', $matches['func_arg']);
?>
Result: string = "$node,$op,$a3,$form,$a4"
bit_kahuna at yahoo dot com
27.03.2009 20:02
how to display a shortened text string with an elipsis, but on word boundaries only.

<?php
function truncate($string, $max = 70, $rep = '...') {

   
$words = preg_split("/[\s]+/", $string);
   
   
$newstring = '';
   
$numwords = 0;
   
    foreach (
$words as $word) {
        if ((
strlen($newstring) + 1 + strlen($word)) < $max) {
           
$newstring .= ' '.$word;
            ++
$numwords;
        } else {
            break;
        }
    }

    if (
$numwords < count($words)) {
       
$newstring .= $rep;
    }
   
    return
$newstring;
}
?>

hope this helps someone!  thanks for all the help from everyone else!!
csaba at alum dot mit dot edu
17.03.2009 22:06
If the task is too complicated for preg_split, preg_match_all might come in handy, since preg_split is essentially a special case.

I wanted to split a string on a certain character (asterisk), but only if it wasn't escaped (by a preceding backslash).  Thus, I should ensure an even number of backslashes before any asterisk meant as a splitter.  Look-behind in a regular expression wouldn't work since the length of the preceding backslash sequence can't be fixed.  So I turned to preg_match_all:

<?php
// split a string at unescaped asterisks
// where backslash is the escape character
$splitter = "/\\*((?:[^\\\\*]|\\\\.)*)/";
preg_match_all($splitter, "*$string", $aPieces, PREG_PATTERN_ORDER);
$aPieces = $aPieces[1];

// $aPieces now contains the exploded string
// and unescaping can be safely done on each piece
foreach ($aPieces as $idx=>$piece)
 
$aPieces[$idx] = preg_replace("/\\\\(.)/s", "$1", $piece);
?>
anajilly
17.07.2008 10:17
<?php
$s
= '<p>bleh blah</p><p style="one">one two three</p>';

$htmlbits = preg_split('/(<p( style="[-:a-z0-9 ]+")?>|<\/p>)/i', $s, -1, PREG_SPLIT_DELIM_CAPTURE);

print_r($htmlbits);
?>

Array
(
    [0] =>
    [1] => <p>
    [2] => bleh blah
    [3] => </p>
    [4] =>
    [5] => <p style="one">
    [6] =>  style="one"
    [7] => one two three
    [8] => </p>
    [9] =>
)

two interesting bits:

1. When using PREG_SPLIT_DELIM_CAPTURE, if you use more than one pair of parentheses, the result array can have members representing all pairs.  See array indexes 5 and 6 to see two adjacent delimiter results in which the second is a subset match of the first.

2. If a parenthesised sub-expression is made optional by a following question mark (ex: '/abc (optional subregex)?/') some split delimiters may be captured in the result while others are not.  See array indexes 1 and 2 to see an instance where the overall match succeeded and returned a delimiter while the optional sub-expression '( style="[-:a-z0-9 ]+")?' did not match, and did not return a delimiter.  This means it's possible to have a result with an unpredictable number of delimiters in the result array.

This second aspect is true irrespective of the number of pairs of parentheses in the regex.  This means: in a regular expression with a single optional parenthesised sub-expression, the overall expression can match without generating a corresponding delimiter in the result.
m dot timmermans at home dot NOSPAM dot nl
29.05.2008 12:56
For people who want to use the double quote to group words/fields, kind of like CSV does, you can use the following expression:
<?php
$keywords
= preg_split( "/[\s,]*\\\"([^\\\"]+)\\\"[\s,]*|[\s,]+/", "textline with, commas and \"quoted text\" inserted", 0, PREG_SPLIT_DELIM_CAPTURE );
?>
Which will result in:
Array
(
    [0] => textline
    [1] => with
    [2] => commas
    [3] => and
    [4] => quoted text
    [5] => inserted
)
crispytwo at yahoo dot com
4.09.2007 22:29
I was having trouble getting the PREG_SPLIT_DELIM_CAPTURE flag to work because I missed reading the "parenthesized expression" in the documentation :-( 

So the pattern should look like:
/(A)/
not just
/A/
and it works as described/expected.
Steve
23.03.2005 17:41
preg_split() behaves differently from perl's split() if the string ends with a delimiter. This perl snippet will print 5:

my @a = split(/ /, "a b c d e ");
print scalar @a;

The corresponding php code prints 6:

<?php print count(preg_split("/ /", "a b c d e ")); ?>

This is not necessarily a bug (nowhere does the documentation say that preg_split() behaves the same as perl's split()) but it might surprise perl programmers.
jetsoft at iinet.net.au
25.09.2004 17:01
To clarify the "limit" parameter and the PREG_SPLIT_DELIM_CAPTURE option,

<?php
$preg_split
('(/ /)', '1 2 3 4 5 6 7 8', 4 ,PREG_SPLIT_DELIM_CAPTURE );
?>

returns:

('1', ' ', '2', ' ' , '3', ' ', '4 5 6 7 8')

So you actually get 7 array items not 4
dave at codewhore dot org
29.05.2002 21:01
The above description for PREG_SPLIT_OFFSET_CAPTURE may be a bit confusing.

When the flag is or'd into the 'flags' parameter of preg_split, each match is returned in the form of a two-element array. For each of the two-element arrays, the first element is the matched string, while the second is the match's zero-based offset in the input string.

For example, if you called preg_split like this:

preg_split('/foo/', 'matchfoomatch', -1, PREG_SPLIT_OFFSET_CAPTURE);

it would return an array of the form:

Array(
  [0] => Array([0] => "match", [1] => 0),
  [1] => Array([1] => "match", [1] => 8)
)

Note that or'ing in PREG_DELIM_CAPTURE along with PREG_SPLIT_OFFSET_CAPTURE works as well.



PHP Powered Diese Seite bei php.net
The PHP manual text and comments are covered by the Creative Commons Attribution 3.0 License © the PHP Documentation Group - Impressum - mail("TO:Reinhard Neidl",...)