PHP
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

POSIX Regex> <PCRE-Funktionen
Last updated: Fri, 10 Oct 2008

view this page in

preg_split

(PHP 4, PHP 5)

preg_splitZerlegt eine Zeichenkette anhand eines regulären Ausdrucks

Beschreibung

array preg_split ( string $Suchmuster , string $Zeichenkette [, int $Limit [, int $Flags ]] )

Zerlegt die angegebene Zeichenkette anhand eines regulären Ausdrucks.

Parameter-Liste

Suchmuster

Der Ausdruck nach dem gesucht werden soll als Zeichenkette

Zeichenkette

Die zu zerlegende Zeichenkette

Limit

Falls angegeben, werden maximal Limit Teilzeichenketten zurückgegeben und falls Limit -1 ist, bedeutet das "kein Limit", was für die Angabe von Flags sinnvoll ist.

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 Zeichenkette als Element 1 besteht.

Rückgabewerte

Gibt ein Array zurück, bestehend aus Teilzeichenketten der Zeichenkette , die an den auf das Suchmuster 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
4.0.0 Den Parameter Flags 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.



POSIX Regex> <PCRE-Funktionen
Last updated: Fri, 10 Oct 2008
 
add a note add a note User Contributed Notes
preg_split
merlinyoda at dotproject dot net
27-Aug-2008 03:55
I response to the post of "harrismw at ids dot org dot au" below: it *is* just as simple as escaping characters! Characters the question mark ('?'), the dollar sign ('$') and all types of "braces" ('(', ')', '{', '}', '[', ']') have special meaning in regular expressions. As noted in the manual above, if you don't need the power and flexibility that regular expressions provide (i.e. you are looking to split on a specific literal string) then you are better off using functions like explode().
harrismw at ids dot org dot au
06-Aug-2008 03:31
So yeah, my nice little function I posted below. Guess what, it doesn't work for all cases.

If you know your way around regular expressions and the like then this might not come as a surprise, but it did surprise me. Basically, certain characters aren't welcome. If you try and include a bit of PHP in your patterns, then it might screw up your entire thing.

E.g.

< ? php if(!$suppressitemPHP) {

(Without the spaces between the < ? and php), isn't welcome, which bit? In this case having a single '{' is the problem. And I also suspect that the '(' and ')' and maybe '<', '?' and '$' are problems as well, but I'm not so sure.

I'm doing my research, and when (if) I come up with an answer, I'll post a revised function which will let me do what I want. (It may be as simple as escaping those chars in the pattern, I'm not sure.)

So yeah, use the function below, it works well, just be careful is all, it doesn't work all the time.
anajilly
17-Jul-2008 10:17
<?
$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.
harrismw at ids dot org dot au
14-Jul-2008 11:45
So, after posting that last post, I actually went and made it more robust.

<?php
/*
@param $pat1 the first pattern
@param $pat2 the second pattern
@param $co string containing what you want to extract and delimiters
@return $ite the text between the two patterns
*/
function getitem($pat1,$pat2,$co)
{
   
$arrayf = preg_split ($pat1, $co);
   
$ite = $arrayf[1];
   
$arrayf = preg_split ($pat2, $ite);
   
$ite = $arrayf[0];
    return
$ite;
}
?>
Yeah, so the previous post could be rendered more succinct, and it allows you to have as many delimiters as you want.
harrismw at ids dot org dot au
13-Jul-2008 03:33
If you have some text of the form:
$part1.'some text'.$part2.'some other text'.$part3
And you want to split out the text, and discard the $partX parts, e.g.
<html><head><title>
My title!
</title></head><body>
My body!
</body></html>
and just keep "My title!" and "My body!", then this code will be of use.
<?php
//defining the delimiters
$part1= '<html><head><title>';
$part2='</title></head><body>';
$part3='</body></html>';
//and the text, for my project I'm getting this information from a text file.
$tempcon = <<<eoa
<html><head><title>
My title!
</title></head><body>
My body!
</body></html>
eoa
;
// defining the patterns.
$pattern1='~'.$part1.'~';
$pattern2='~'.$part2.'~';
$pattern3='~'.$part3.'~';

//Finding the title
   
$arrayf = preg_split ($pattern1, $tempcon); //2 sort out the title
   
$title = $arrayf[1];
   
$arrayf = preg_split ($pattern2, $title); //2
   
$title = $arrayf[0];
//Finding the body text.
   
$arrayf = preg_split ($pattern2, $tempcon); //2 sort out the content
   
$content = $arrayf[1];
   
$arrayf = preg_split ($pattern3, $content); //2
   
$content = $arrayf[0];

//And display.
echo $title.'<br>'.$content;
?>

I looked long and hard, and I just couldn't find an example of doing this, so here you go. Of course, I would love to be able to use a single call to preg_split, but I haven't worked that out.
m dot timmermans at home dot NOSPAM dot nl
29-May-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
)
fdmembership at example dot com
27-May-2008 04:08
When I try to get \n delimited lines to an array from a file, preg_split gives one more array element which contains null string. Assume file contains

line1
line2

$lines = preg_split("/\n/", fread($fh, filesize($filename)));

$lines{
 [0] => line1
 [1] => line2
 [2] =>
}
Same problem exists for explode as weel.
(this might be a feature of "PHP", not a problem.)
crispytwo at yahoo dot com
04-Sep-2007 10: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.
me
14-Nov-2006 02:56
[Editor's Note: You can use php's wordwrap() to do the exact same thing]

This script splits a text into portions of a defined max. size, which will never be exceeded, and doesnt cut words. (Per portion it adds as many words as possible without exceeding the char-limit)

the only exception where a portion would be bigger than the limit, is when there's a word thats longer than the max_size, but you could quite easily change the script so it regards this.

<?
$str= 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.';

$max_size = 50;
$words = preg_split("/[\040]+/", $str, -1);

$r=0;
for($i=0; $i < count($words); $i++) {
if (strlen($line[$r] . $words[$i] . ' ') < $max_size) $line[$r] .= $words[$i] . ' ';
else
    {
        $r++;
        $line[$r] .= $words[$i] . ' ';
    }
}
print_r ($line);
?>

Result:

Array
(
    [0] => Lorem ipsum dolor sit amet, consectetur
    [1] => adipisicing elit, sed do eiusmod tempor
    [2] => incididunt ut labore et dolore magna aliqua. Ut
    [3] => enim ad minim veniam, quis nostrud exercitation
    [4] => ullamco laboris nisi ut aliquip ex ea commodo
    [5] => consequat. Duis aute irure dolor in
    [6] => reprehenderit in voluptate velit esse cillum
    [7] => dolore eu fugiat nulla pariatur. Excepteur sint
    [8] => occaecat cupidatat non proident, sunt in culpa
    [9] => qui officia deserunt mollit anim id est laborum.
)
superzouz at hotmail dot com
04-Dec-2005 02:53
Be advised

$arr = preg_split("/x/", "x" );
print_r($arr);

will output:

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

That is it will catch the 2 empty string on each side of the delimiter.
Steve
23-Mar-2005 05: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:

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-Sep-2004 05:01
To clarify the "limit" parameter and the PREG_SPLIT_DELIM_CAPTURE option,

$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-May-2002 09: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.

POSIX Regex> <PCRE-Funktionen
Last updated: Fri, 10 Oct 2008
 
 
show source | credits | sitemap | contact | advertising | mirror sites