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

Verlauf / Chronik / History: (1) anzeigen

Sie sind hier:
Doku-StartseitePHP-HandbuchFunktionsreferenzTextverarbeitungReguläre Ausdrücke (POSIX-erweitert)POSIX Regex-Funktionensplit

Ein Service von Reinhard Neidl - Webprogrammierung.

POSIX Regex-Funktionen

<<eregi

spliti>>

split

(PHP 4, PHP 5)

splitZerlegt eine Zeichenkette anhand eines regulären Ausdrucks in ein Array

Beschreibung

array split ( string $pattern , string $string [, int $limit ] )

Zerlegt string anhand eines regulären Ausdrucks in ein Array.

Warnung

Diese Funktion ist seit PHP 5.3.0 DEPRECATED (veraltet). Sich auf diese Funktion zu verlassen ist in keiner Weise empfehlenswert.

Parameter-Liste

pattern

Regulärer Ausdruck mit Berücksichtigung der Groß- und Kleinschreibung

Wenn Sie eine Zerlegung an Zeichen vornehmen, die in regulären Ausdrücken als besondere Zeichen betrachtet werden, müssen Sie diese entsprechend kennzeichnen. Wenn Sie der Ansicht sind, split() (oder, bei diesem Thema, eine andere Regex-Funktion) verhalte sich seltsam, lesen Sie bitte die Datei regex.7, die sich im regex/ Unterverzeichnis ihrer PHP-Distribution befindet. Da sie im manpage-Fomat vorliegt, sollten Sie einen Befehl der Art man /usr/local/src/regex/regex.7 verwenden, um sie zu lesen.

string

Die zu durchsuchende Zeichenkette

limit

Wenn limit gesetzt wurde, enthält das zurückgegebene Array höchstens limit Elemente, von denen das letzte den ganzen Rest von string enthält.

Rückgabewerte

Gibt ein Array mit Zeichenketten zurück, die jeweils eine Teilzeichenkette von string sind. Diese Teilzeichenketten entstehen durch Zerlegung von string an den durch den regulären Ausdruck pattern bestimmten Stellen unter Berücksichtigung der Groß- und Kleinschreibung.

Wenn pattern n mal vorkommt, enhält das zurückgegebene Array n+1 Elemente. Kommt pattern zum Beispiel überhaupt nicht vor, wird ein Array mit nur einem Element zurückgegeben. Das gilt natürlich auch, wenn string leer ist. Bei Auftreten eines Fehlers gibt split() FALSE zurück.

Beispiele

Beispiel #1 split()-Beispiel

Um die ersten vier Felder einer Zeile von /etc/passwd abzuspalten:

<?php
list($user$pass$uid$gid$extra) =
    
split(":"$passwd_line5);
?>

Beispiel #2 split()-Beispiel

Um ein Datum zu analysieren, das durch Schrägstriche, Punkte oder Bindestriche getrennt ist:

<?php
// Trennzeichen darf ein Schrägstrich, Punkt oder Bindestrich sein
$datum "04/30/1973";
list (
$monat$tag$jahr) = split('[/.-]'$datum);
echo 
"Monat: $monat; Tag: $tag; Jahr: $jahr<br />\n";
?>

Anmerkungen

Hinweis:

Seit PHP 5.3.0 ist die regex-Erweiterung zugunsten der PCRE-Erweiterung als veraltete markiert. Ein Aufruf dieser Funktion wird eine E_DEPRECATED-Notice ausgeben. Sie können sich die Liste der Unterschiede ansehen, wenn Sie Hilfe beim Umstieg auf PCRE benötigen.

Tipp

Die Funktion preg_split(), die eine zu Perl kompatible Syntax regulärer Ausdrücke verwendet, ist häufig die schnellere Alternative zu split(). Wenn Sie die Fähigkeiten regulärer Ausdrücke nicht benötigen, ist die Verwendung von explode() schneller, weil diese Funktion nicht unter der Last der Engine für reguläre Ausdrücke steht.

Tipp

Wenn Sie nach einer Möglichkeit suchen, das Verhalten von Perls @chars = split('', $str) nachzuahmen, schauen Sie sich bitte die Beispiele für preg_split() oder str_split() an.

Siehe auch

  • preg_split() - Zerlegt eine Zeichenkette anhand eines regulären Ausdrucks
  • spliti() - Zerlegt eine Zeichenkette anhand eines regulären Ausdrucks ohne Berücksichtigung von Groß-/Kleinschreibung in ein Array
  • str_split() - Konvertiert einen String in ein Array
  • explode() - Teilt einen String anhand einer Zeichenkette
  • implode() - Verbindet Array-Elemente zu einem String
  • chunk_split() - Zerlegt einen String in Teile gleicher Länge
  • wordwrap() - Bricht einen String nach einer bestimmten Anzahl Zeichen um


38 BenutzerBeiträge:
- Beiträge aktualisieren...
admin at ejaz dot com dot sa
14.07.2010 10:23
Use split with implode to fetch array values or elements:

<?php
list( $ip, $line, $filename) = split( ',', implode( ',', array('100.1.2.3','23','/index.php') ) );

echo
$ip.$line.$filename;
?>

Result :

100.1.2.3
23
/index.php
Bob
25.04.2009 3:58
I was interested in the performance of various tokenizing algorithms, in particular splitting a string by a list of tokens. I've compared 3 methods, including a custom function based on strtok().
My aim was to split a MySQL type definition into its various parts, i.e. split "int(10) unsigned zerofill" to Array( 1 => "int", 2 => "10", 3 => " unsigned zerofill" )
This is the code I ran:
<?php
function getmicrotime()

{

    list(
$usec, $sec) = explode(" ",microtime());

    return ((float)
$usec + (float)$sec);

}

function
toksplit($string, $tokens)
{
   
$val = array();
   
$v = strtok($string, $tokens);
    do
$val[] = $v;
    while(
$v = strtok($tokens));
    return
$val;
}

echo
"<pre>";

$string = "int(10) unsigned zerofill";
$ntrials = 100000;

for(
$i = 0, $t = getmicrotime(); $i < $ntrials; ++$i) $toksplit_result = toksplit($string, '()');
$time = getmicrotime()-$t;
$avg = $time/$ntrials;
echo
"toksplit(): $avg\n";
print_r($toksplit_result);

for(
$i = 0, $t = getmicrotime(); $i < $ntrials; ++$i) $split_result = split('[()]', $string);
$time = getmicrotime()-$t;
$avg = $time/$ntrials;
echo
"split(): $avg\n";
print_r($split_result);

for(
$i = 0, $t = getmicrotime(); $i < $ntrials; ++$i) $preg_split_result = preg_split('/[()]/', $string);
$time = getmicrotime()-$t;
$avg = $time/$ntrials;
echo
"preg_split(): $avg\n";
print_r($preg_split_result);

echo
"</pre>";
?>
These were the results:
toksplit(): 1.94901299477E-5
Array
(
    [0] => int
    [1] => 100
    [2] =>  unsigned zerofill
)
split(): 1.50095391273E-5
Array
(
    [0] => int
    [1] => 100
    [2] =>  unsigned zerofill
)
preg_split(): 1.82743000984E-5
Array
(
    [0] => int
    [1] => 100
    [2] =>  unsigned zerofill
)

Interestingly, split() was the fastest.
I also modified my test to also strip whitespace from each token, changing the patterns to "\s*[()]\s*" and adding a trim() call to the toksplit() function. The results went from fastest to slowest: preg_split(), split(), toksplit().
I would infer from this that split() is the fastest if you want to simply split by a list of delimiters. However, if you want to split by a more complicated pattern, preg_split() is the best.
strtok() is clearly slower.
NOTE: if you want to split by a single delimiter (not a list or pattern), use explode().
charles at etherscapes dot com
18.03.2009 18:33
This function just makes sure there are 10 digits in a string, no matter what other characters there are. I'm using it for validating any phone number in the world and requiring an area code. It's far from perfect, but since I don't know which country the phone number is for, it's good enough for my purposes:

<?php
function validPhone($str) {
   
$digits = split("[0-9]",$str);
    return
count($digits)>10;
}
?>
Greg Levine
4.12.2008 22:45
I kept running into the same issue Chris Tyler experienced with lewis [ at t] hcoms [d dot t] co [d dot t] uk's function before realizing that Chris had come up with a solution. However, that solution was just a little off it seems, unless your CSV only contains one line.

If you simply add another --length; in the place you suggested, then the function will always trim the last two characters on the line. Since the newline character is the last character on the line and the redundant quote (or other enclosure) is the second to last character, this works for the final segment. But when parsing segments that do not include a newline character, you end up trimming the redundant enclosure and the last character before the enclosure.

For example,

"he","she","him","her"\r\n

becomes

[0] => h
[1] => sh
[2] => hi
[3] => her

Since the segment could end with the enclosure (i.e., ") or the enclosure followed by the newline (i.e., "\r\n), you have make sure you are only adding another --length; when the latter is the case. Replacing the code block that you suggested with the following will do the trick.

# Is the last thing a newline?
if( $char == $newline )
{
    # Well then get rid of it
    --$length;
}

# Is the last thing a quote?
if( $trim_quote )
{
    # Well then get rid of it
    --$length;
}

I've tested this only for the purposes of the script I'm working on at this time. So, there could be other bugs I haven't come across, but this seems like the easiest way to eliminate the redundant enclosure.
sue_hok at hotmail dot com
11.09.2008 20:26
This function basically is to split the string from right with limit
<?php

function split_right($pattern,$input,$len=0)
    {
if(
$len==0)
    return
split($pattern,$input);

           
$tempInput = split($pattern,$input);
           
$tempInput = array_reverse($tempInput);
           
$tempArray = array();
           
$ArrayIndex=0;
           
$indexCount=0;
            foreach(
$tempInput as $values)
            {
                if(
$indexCount<$len)
                {
                   
$tempArray[$ArrayIndex]=$values;
                    if(
$indexCount<$len-1)
                       
$ArrayIndex++;
                }
                else
                {
                       
$tempArray[$ArrayIndex]=$values.$pattern.$tempArray[$ArrayIndex];
                   
                }
               
               
$indexCount++;

            }
            return
array_reverse($tempArray);
    }

//For Example:
$string = "Hello World Split";
print_r(split(" ",$string,2));
print_r(split_right(" ",$string,2));

/*OutPut
Array
(
    [0] => Hello
    [1] => World Split
)

Array
(
    [0] => Hello World
    [1] => Split
)
*/

?>
anthonyhoivik at gmail dot com
15.08.2008 17:45
Convert a full name ( in one text input ) to a first, middle, last.

$fullname = $_POST['fullname'];
  list($first, $middle, $last) = split(' ', $fullname);
  if ( !$last ) {
    $last = $middle;
    unset($middle);
  }
pascalaschwandenNOSPAM at gmail dot com
13.07.2008 21:12
The following code will mimick the explode functionality: explode( " ", $s );  The difference, of course, is that the split method takes a regular expression instead of a string.

$s = "Split this sentence by spaces";
$words = split("[ ]+", $s);
print_r($words);

Output:
Array
(
    [0] => Split
    [1] => this
    [2] => sentence
    [3] => by
    [4] => spaces
)
http://www.codesplunk.com/nr/questions/php12.html
Chris Tyler
10.04.2008 0:25
Thank you Dave for your code below.  Here is one change I made to avoid a redundant quote at the end of some lines (at least when I used excel: 

Added another --length;  into the if statement below:

                // Is the last thing a quote?
                if ($trim_quote){
                    // Well then get rid of it
                    --$length;
        // ADD TO FIX extra quote
    --$length;
                }
lewis [ at t] hcoms [d dot t] co [d dot t] uk
26.03.2008 0:32
Those of you trying to use split for CSV, it won't always work as expected. Instead, try using a simple stack method:

<?php

   
/**
     * Create a 2D array from a CSV string
     *
     * @param mixed $data 2D array
     * @param string $delimiter Field delimiter
     * @param string $enclosure Field enclosure
     * @param string $newline Line seperator
     * @return
     */
   
function parse($data, $delimiter = ',', $enclosure = '"', $newline = "\n"){
       
$pos = $last_pos = -1;
       
$end = strlen($data);
       
$row = 0;
       
$quote_open = false;
       
$trim_quote = false;

       
$return = array();

       
// Create a continuous loop
       
for ($i = -1;; ++$i){
            ++
$pos;
           
// Get the positions
           
$comma_pos = strpos($data, $delimiter, $pos);
           
$quote_pos = strpos($data, $enclosure, $pos);
           
$newline_pos = strpos($data, $newline, $pos);

           
// Which one comes first?
           
$pos = min(($comma_pos === false) ? $end : $comma_pos, ($quote_pos === false) ? $end : $quote_pos, ($newline_pos === false) ? $end : $newline_pos);

           
// Cache it
           
$char = (isset($data[$pos])) ? $data[$pos] : null;
           
$done = ($pos == $end);

           
// It it a special character?
           
if ($done || $char == $delimiter || $char == $newline){

               
// Ignore it as we're still in a quote
               
if ($quote_open && !$done){
                    continue;
                }

               
$length = $pos - ++$last_pos;

               
// Is the last thing a quote?
               
if ($trim_quote){
                   
// Well then get rid of it
                   
--$length;
                }

               
// Get all the contents of this column
               
$return[$row][] = ($length > 0) ? str_replace($enclosure . $enclosure, $enclosure, substr($data, $last_pos, $length)) : '';

               
// And we're done
               
if ($done){
                    break;
                }

               
// Save the last position
               
$last_pos = $pos;

               
// Next row?
               
if ($char == $newline){
                    ++
$row;
                }

               
$trim_quote = false;
            }
           
// Our quote?
           
else if ($char == $enclosure){

               
// Toggle it
               
if ($quote_open == false){
                   
// It's an opening quote
                   
$quote_open = true;
                   
$trim_quote = false;

                   
// Trim this opening quote?
                   
if ($last_pos + 1 == $pos){
                        ++
$last_pos;
                    }

                }
                else {
                   
// It's a closing quote
                   
$quote_open = false;

                   
// Trim the last quote?
                   
$trim_quote = true;
                }

            }

        }

        return
$return;
    }

?>

This *should* work for any valid CSV string, regardless of what it contains inside its quotes (using RFC 4180). It should also be faster than most of the others I've seen. It's very simple in concept, and thoroughly commented.
Dave Walter
1.03.2008 0:39
In response to  the getCSVValues() function posted by justin at cam dot org, my testing indicates that it has a problem with a CSV string like this:

1,2,"3,""4,5"",6",7

This parses as:

array(6) {
  [0]=>
  string(1) "1"
  [1]=>
  string(1) "2"
  [2]=>
  string(4) "3,"4"
  [3]=>
  string(1) "5"
  [4]=>
  string(0) ""
  [5]=>
  string(1) "7"
}

instead of:

array(4) {
  [0]=>
  string(1) "1"
  [1]=>
  string(1) "2"
  [2]=>
  string(9) "3,"4,5",6"
  [3]=>
  string(1) "7"
}

To fix this, I changed the second substr_count to look for an odd number of quotes, as opposed to any quotes at all:

<?php
function getCSVValues($string, $separator=",")
{
   
$elements = explode($separator, $string);
    for (
$i = 0; $i < count($elements); $i++) {
       
$nquotes = substr_count($elements[$i], '"');
        if (
$nquotes %2 == 1) {
            for (
$j = $i+1; $j < count($elements); $j++) {
                if (
substr_count($elements[$j], '"') %2 == 1) { // Look for an odd-number of quotes
                    // Put the quoted string's pieces back together again
                   
array_splice($elements, $i, $j-$i+1,
                       
implode($separator, array_slice($elements, $i, $j-$i+1)));
                    break;
                }
            }
        }
        if (
$nquotes > 0) {
           
// Remove first and last quotes, then merge pairs of quotes
           
$qstr =& $elements[$i];
           
$qstr = substr_replace($qstr, '', strpos($qstr, '"'), 1);
           
$qstr = substr_replace($qstr, '', strrpos($qstr, '"'), 1);
           
$qstr = str_replace('""', '"', $qstr);
        }
    }
    return
$elements;
}
?>
Nate Sweet
31.05.2007 22:39
This function takes a string like this...

this=cool that="super cool" thing='ridiculous cool'

And gives you an associative array of names and values.

function parseNameValues ($text) {
    $values = array();
    if (preg_match_all('/([^=\s]+)=("(?P<value1>[^"]+)"|' . '\'(?P<value2>[^\']+)\'|(?P<value3>.+?)\b)/', $text, $matches, PREG_SET_ORDER))
        foreach ($matches as $match)
            $values[trim($match[1])] = trim(@$match['value1'] . @$match['value2'] . @$match['value3']);
    return $values;
}

(regex broken into two strings so it won't be too long for this webpage)
Mike
19.05.2007 7:40
// Split a string into words on boundaries of one or more spaces, tabs or new-lines
$s = "Please cut   \t me \n in pieces";
$words = split("[\n\r\t ]+", $s);
print_r($words);

// Output:
Array
(
    [0] => Please
    [1] => cut
    [2] => me
    [3] => in
    [4] => pieces
)
Jort
14.03.2007 21:53
If you are looking for EITHER open square brackets OR close square brackets, then '[[]]' won't work (reasonably expected), but neither will '[\[\]]', nor with any number of escapes. HOWEVER, if your pattern is '[][]' it will work.
justin at cam dot org
16.02.2007 7:21
The previous solution assumes that a quoted string always starts a new element (true in real CSV files, but not in my application). The following routine does not make any such assumptions. It also deals with pairs of quotes and does not use any regular expressions.

<?php
function getCSVValues($string, $separator=",")
{
   
$elements = explode($separator, $string);
    for (
$i = 0; $i < count($elements); $i++) {
       
$nquotes = substr_count($elements[$i], '"');
        if (
$nquotes %2 == 1) {
            for (
$j = $i+1; $j < count($elements); $j++) {
                if (
substr_count($elements[$j], '"') > 0) {
                   
// Put the quoted string's pieces back together again
                   
array_splice($elements, $i, $j-$i+1,
                       
implode($separator, array_slice($elements, $i, $j-$i+1)));
                    break;
                }
            }
        }
        if (
$nquotes > 0) {
           
// Remove first and last quotes, then merge pairs of quotes
           
$qstr =& $elements[$i];
           
$qstr = substr_replace($qstr, '', strpos($qstr, '"'), 1);
           
$qstr = substr_replace($qstr, '', strrpos($qstr, '"'), 1);
           
$qstr = str_replace('""', '"', $qstr);
        }
    }
    return
$elements;
}
?>
Theodule
24.01.2007 17:41
A little modification from dan jones.
_New_: I had a parameter to specify separator (default ",").
_Fix _: double-quotes who appear in a spreadsheet exported to CSV, they get escaped by doubling them. So I remplace them by ' caracter
<?php
function getCSVValues($string,$separator=",")
{
   
$string = str_replace('""', "'", $string);
   
// split the string at double quotes "
   
$bits = explode('"',$string);
   
$elements = array();
    for (
$i=0; $i < count($bits) ; $i++ ) {
       
/*
        odd numbered elements would have been
        enclosed by double quotes
        even numbered elements would not have been
        */
       
if (($i%2) == 1) {
           
/* if the element number is odd add the
            whole string  to the output array */
           
$elements[] = $bits[$i];
        } else
        {
           
/* otherwise split the unquoted stuff at commas
            and add the elements to the array */
           
$rest = $bits[$i];
           
$rest = preg_replace("/^".$separator."/","",$rest);
           
$rest = preg_replace("/".$separator."$/","",$rest);
           
$elements = array_merge($elements,explode($separator,$rest));
        }
    }
    return
$elements;
}
?>
dan dot jones at lunarfish dot co dot uk
17.08.2006 14:24
Here's a function to split a string into csv values where they are optionally enclosed by " to allow values with commas in.

I think it works. Let me know if I'm wrong.

Cheers. Dan

function getCSVValues($string) {
   // split the string at double quotes "
   $bits = split('"',$string);
   $elements = array();
   for ($i=0;$i<count($bits);$i++) {
      /*
          odd numbered elements would have been
          enclosed by double quotes
          even numbered elements would not have been
      */
      if (($i%2) == 1) {
         /* if the element number is odd add the
             whole string  to the output array */
         $elements[] = $bits[$i];
      } else {
         /* otherwise split the unquoted stuff at commas
             and add the elements to the array */
         $rest = $bits[$i];
         $rest = preg_replace("/^,/","",$rest);
         $rest = preg_replace("/,$/","",$rest);
         $elements = array_merge($elements,split(',',$rest));
      }
   }
   return $elements;
}
destes at ix dot netcom dot com
14.02.2006 9:15
Some corrections to robin-at-teddyb's CSV splitting function.  Recall that the point of this is to properly implement a split() function that handles data exported to CSV, where data containing commas gets quote-delimited.

* Problem 1: As jh-at-junetz pointed out, the +1 in robin's nonquoted splitting command mistakenly adds an extra element to the resulting array.
* Problem 2: If consecutive fields are quote-delimited, the remaining "separator" between them only contains one delimiter and no actual fields - so an extra element gets added to the parsed array.
* Problem 3: When double-quotes appear in a spreadsheet exported to CSV, they get escaped by doubling them, i.e. a data field reading "this is a test of a "special" case" gets written to CSV as, "this is a test of a ""special"" case".  These quotes are also interpreted as top-level delimiters and (mistakenly) add extra array elements to the output. 

I have hacked a conversion of "" to a single quote ( ' ), but a truly clever preg_split for the top-level splitter (instead of the explode) might preserve the original doubled "s without bugging up the top-level parsing.  i.e., a smarter man than I could solve the problem rather than avoiding it by replacing the bad data.

(current) Solution:

<?php

function quotesplit( $splitter=',', $s, $restore_quotes=0 ) {
   
// hack because i'm a bad programmer - replace doubled "s with a '
   
$s = str_replace('""', "'", $s);
   
   
//First step is to split it up into the bits that are surrounded by quotes
    //and the bits that aren't. Adding the delimiter to the ends simplifies
    //the logic further down
   
$getstrings = explode('"', $splitter.$s.$splitter);

   
//$instring toggles so we know if we are in a quoted string or not
   
$delimlen = strlen($splitter);
   
$instring = 0;

    while (list(
$arg, $val) = each($getstrings)) {
        if (
$instring==1) {
            if(
$restore_quotes ) {
               
//Add the whole string, untouched to the previous value in the array
               
$result[count($result)-1] = $result[count($result)-1].'"'.$val.'"';
            } else {
               
//Add the whole string, untouched to the array
               
$result[] = $val;
            }
           
$instring = 0;
        } else {
           
// check that we have data between multiple $splitter delimiters
                       
if ((strlen($val)-$delimlen) >= 1) {
           
               
//Break up the string according to the delimiter character
                //Each string has extraneous delimiters around it (inc the ones we added
                //above), so they need to be stripped off
               
$temparray = split($splitter, substr($val, $delimlen, strlen($val)-$delimlen-$delimlen ) );

                while(list(
$iarg, $ival) = each($temparray)) {
                   
$result[] = trim($ival);
                }
            }
           
// else, the next element needing parsing is a quoted string and the comma
            // here is just a single separator and contains no data, so skip it

           
$instring = 1;
        }
    }

    return
$result;
}

?>
RE: gcerretini at technica dot net /UTF8
8.02.2006 13:26
Original problem:
=================

I've try using split function.

<?php
$ferro
="2&#65533;12";
$valore=split("[&#65533;]",$ferro);
echo
$ferro."<br>";
echo
"p1-".$valore[0]."<br>";
echo
"p2-".$valore[1]."<br>";
echo
"p3-".$valore[2]."<br>";
$ferro="2d12";
$valore=split("[d]",$ferro);
echo
$ferro."<br>";
echo
"p1-".$valore[0]."<br>";
echo
"p2-".$valore[1]."<br>";
echo
"p3-".$valore[2]."<br>";
?>

This return:
============

2&#65533;12
p1-2
p2-
p3-12
2d12
p1-2
p2-12
p3-

I use charset UTF-8. When I use char &#65533; the split function ad an empty string between "2" and "12"... Why?

Explanation:
============

UTF-8 charset codes some characters (like the "&#65533;" character) into two bytes. In fact the regular expresion "[&#65533;]" contains 4 bytes (4 non-unicode characters). To demonstrate the real situation I wrote following example:

$ferro="2de12";
$valore=split("[de]",$ferro);
echo $ferro."<br>";
echo "p1-".$valore[0]."<br>";
echo "p2-".$valore[1]."<br>";
echo "p3-".$valore[2]."<br>";

This returns:
=============

2d12
p1-2
p2-
p3-12

4.12.2005 14:57
Be advised

$arr = split("x", "x" );
print_r($arr);

will output:

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

That is it will catch 2 empty strings on each side of the delimiter.
franz at fholzinger dot com
4.11.2005 13:34
The example from ramkumar rajendran did not work.
$line = split("/\n", $input_several_lines_long);
I do not know why this does not work for me.

The following has worked for me to get a maximum of 2 array parts separated by the first new line (independant if saved under UNIX or WINDOWS):
$line = preg_split('/[\n\r]+/',$input_several_lines_long,2);
Also empty lines are not considered here.
passtschu AT freenet DOT de
24.09.2005 9:09
divide a string with a template. the "template dividers" are the keys for the output array.

<?PHP
function string2array ($string, $template){
 
#search defined dividers
 
preg_match_all ("|%(.+)%|U", $template, $template_matches);
 
#replace dividers with "real dividers"
 
$template = preg_replace ("|%(.+)%|U", "(.+)", $template);
 
#search matches
 
preg_match ("|" . $template . "|", $string, $string_matches);
 
#[template_match] => $string_match
 
foreach ($template_matches[1] as $key => $value){
    
$output[$value] = $string_matches[($key + 1)];
  }
  return
$output;
}

$string1 = 'www.something.com 66.196.91.121 - - [01/Sep/2005:04:20:39 +0200] "GET /robots.txt HTTP/1.0" 200 49 "-"';
$string2= '%Domain% %IP% - %User% \[%Date%:%Time% %TimeZone%\] "%Method% %Request% %Protocol%" %ServerCode% %Bytes% "%Referer%"';

print_r (string2array ($string1, $string2));

/*
Array

(
  [ServerAddress] => www.something.com
  [IP] => 66.196.91.121
  [User] => -
  [Date] => 01/Sep/2005
  [Time] => 04:20:39
  [TimeZone] => +0200
  [Method] => GET
  [Request] => /robots.txt
  [Protocol] => HTTP/1.0
  [ServerCode] => 200
  [Bytes] => 49
  [Referer] => -
)
*/
?>
robin at teddyb dot org
30.06.2005 6:01
Actually, this version is better than the last I submitted.  The goal here is to be able to engage in *multiple* delimeter removal passes; for all but the last pass, set the third value to "1", and everything should go well.

    function quotesplit( $splitter=',', $s, $restore_quotes=0 )
    {
        //First step is to split it up into the bits that are surrounded by quotes
        //and the bits that aren't. Adding the delimiter to the ends simplifies
        //the logic further down

        $getstrings = explode('"', $splitter.$s.$splitter);

        //$instring toggles so we know if we are in a quoted string or not
        $delimlen = strlen($splitter);
        $instring = 0;

        while (list($arg, $val) = each($getstrings))
        {
            if ($instring==1)
            {
                if( $restore_quotes )
                {
                    //Add the whole string, untouched to the previous value in the array
                    $result[count($result)-1] = $result[count($result)-1].'"'.$val.'"';
                } else {
                    //Add the whole string, untouched to the array
                    $result[] = $val;
                }
                $instring = 0;
            }
            else
            {
                //Break up the string according to the delimiter character
                //Each string has extraneous delimiters around it (inc the ones we added
                //above), so they need to be stripped off
                $temparray = split($splitter, substr($val, $delimlen, strlen($val)-$delimlen-$delimlen+1 ) );

                while(list($iarg, $ival) = each($temparray))
                {
                    $result[] = trim($ival);
                }
                $instring = 1;
            }
        }

        return $result;
    }
robin at teddyb dot org
30.06.2005 5:50
wchris's quotesplit assumes that anything that is quoted must also be a complete delimiter-seperated entry by itself.  This version does not.  It also uses split's argument order.

    function quotesplit( $splitter=',', $s )
    {
        //First step is to split it up into the bits that are surrounded by quotes
        //and the bits that aren't. Adding the delimiter to the ends simplifies
        //the logic further down

        $getstrings = explode('"', $splitter.$s.$splitter);

        //$instring toggles so we know if we are in a quoted string or not
        $delimlen = strlen($splitter);
        $instring = 0;

        while (list($arg, $val) = each($getstrings))
        {
            if ($instring==1)
            {
                //Add the whole string, untouched to the previous value in the array
                $result[count($result)-1] = $result[count($result)-1].$val;
                $instring = 0;
            }
            else
            {
                //Break up the string according to the delimiter character
                //Each string has extraneous delimiters around it (inc the ones we added
                //above), so they need to be stripped off
                $temparray = split($splitter, substr($val, $delimlen, strlen($val)-$delimlen-$delimlen+1 ) );

                while(list($iarg, $ival) = each($temparray))
                {
                    $result[] = trim($ival);
                }
                $instring = 1;
            }
        }

        return $result;
    }
wchris
18.02.2005 12:53
moritz's quotesplit didn't work for me. It seemed to split on a comma even though it was between a pair of quotes. However, this did work:

function quotesplit($s, $splitter=',')
{
//First step is to split it up into the bits that are surrounded by quotes and the bits that aren't. Adding the delimiter to the ends simplifies the logic further down

    $getstrings = split('\"', $splitter.$s.$splitter);

//$instring toggles so we know if we are in a quoted string or not
    $delimlen = strlen($splitter);
    $instring = 0;

    while (list($arg, $val) = each($getstrings))
    {
        if ($instring==1)
        {
//Add the whole string, untouched to the result array.
            $result[] = $val;
            $instring = 0;
        }
        else
        {
//Break up the string according to the delimiter character
//Each string has extraneous delimiters around it (inc the ones we added above), so they need to be stripped off
            $temparray = split($splitter, substr($val, $delimlen, strlen($val)-$delimlen-$delimlen ) );

            while(list($iarg, $ival) = each($temparray))
            {
                $result[] = trim($ival);
            }
            $instring = 1;
        }
    }
    return $result;
}
ramkumar rajendran
17.01.2005 19:09
A correction to a earlier note
If you want to use split to check on line feeds (\n), the following won't work:

$line = split("\n", $input_several_lines_long);

You really have to do this instead, notice the second slash:
$line = split("/\n", $input_several_lines_long);

Took me a little while to figure to do
claes at dot2me.com
4.11.2004 1:10
Though this is obvious, the manual is a bit incorrect when claiming that the return will always be 1+number of time the split pattern occures.  If the split pattern is the first part of the string, the return will still be 1.  E.g.

$a = split("zz," "zzxsj.com");
count($a);

=> 1.

The return of this can not in anyway be seperated from the return where the split pattern is not found.
moritz
9.04.2004 20:54
Often you want to split CSV-Like data, so this is the function for this :)

It splits data formatted like:

1,2,3
-> [1,2,3]

1 , 3, 4
-> [1,3,4]

one; two;three
-> ['one','two','three']

"this is a string", "this is a string with , and ;", 'this is a string with quotes like " these', "this is a string with escaped quotes \" and \'.", 3
-> ['this is a string','this is a string with , and ;','this is a string with quotes like " these','this is a string with escaped quotes " and '.',3]

function quotesplit($s)
{
    $r = Array();
    $p = 0;
    $l = strlen($s);
    while ($p < $l) {
        while (($p < $l) && (strpos(" \r\t\n",$s[$p]) !== false)) $p++;
        if ($s[$p] == '"') {
            $p++;
            $q = $p;
            while (($p < $l) && ($s[$p] != '"')) {
                if ($s[$p] == '\\') { $p+=2; continue; }
                $p++;
            }
            $r[] = stripslashes(substr($s, $q, $p-$q));
            $p++;
            while (($p < $l) && (strpos(" \r\t\n",$s[$p]) !== false)) $p++;
            $p++;
        } else if ($s[$p] == "'") {
            $p++;
            $q = $p;
            while (($p < $l) && ($s[$p] != "'")) {
                if ($s[$p] == '\\') { $p+=2; continue; }
                $p++;
            }
            $r[] = stripslashes(substr($s, $q, $p-$q));
            $p++;
            while (($p < $l) && (strpos(" \r\t\n",$s[$p]) !== false)) $p++;
            $p++;
        } else {
            $q = $p;
            while (($p < $l) && (strpos(",;",$s[$p]) === false)) {
                $p++;
            }
            $r[] = stripslashes(trim(substr($s, $q, $p-$q)));
            while (($p < $l) && (strpos(" \r\t\n",$s[$p]) !== false)) $p++;
            $p++;
        }
    }
    return $r;
}
alphibia at alphibia dot com
31.03.2004 16:19
I'd like to correct myself, I found that after testing my last solution it will create 5 lines no matter what... So I added this to make sure that it only displays 5 if there are five newlines. :-)

<?php
    $MaxNewLines
= 5;

   
$BRCount = substr_count($Message, '<br />'); 
    if (
$BRCount<$MaxNewLines)
   
$MaxNewLines=$BRCount;
    else if(
$BRCount == 0)
   
$MaxNewLines=1;

   
$Message = str_replace(chr(13), "<br />", $Message);
   
$MessageArray = split("<br />", $Message, $MaxNewLines);
   
$Message = ""; $u=0;
    do    {
   
$Message.=$MessageArray[$u].'<br />';
   
$u++;
    } while(
$u<($MaxNewLines-1));
   
$Message.=str_replace("<br />"," ",$MessageArray[$u]);
   
?>

-Tim
http://www.alphibia.com
nomail at please dot now
21.11.2003 18:33
If you want to use split to check on line feeds (\n), the following won't work:

$line = split("\n", $input_several_lines_long);

You really have to do this instead, notice the second slash:
$line = split("\\n", $input_several_lines_long);

Took me a little while to figure out.
krahn at niehs dot nih dot gov
24.10.2003 21:14
> strange things happen with split
> this didn't work
> $vontag $vonmonat were empty strings
...
> list ($vontag , $vonmonat) = split ('.' , $fromdate); // << bad

Split is acting exactly as it should; it splits on regular expressions.
A period is a regular expression pattern for a single character.
So, an actual period must be escaped with a backslash:  '\.'
A period within brackets is not an any-character pattern, because it does
not make sense in that context.

Beware that regular expressions can be confusing becuase there
are a few different varieties of patterns.
dalu at uni dot de
8.10.2003 21:26
php4.3.0

strange things happen with split

this didn't work
$vontag $vonmonat were empty strings

<?php
function ckdate($fromdate="01.01", $todate="31.12")
{
   
$nowyear = date("Y");
    list (
$vontag , $vonmonat) = split ('.' , $fromdate); // << bad
   
$vondatum = "$nowyear-$vonmonat-$vontag";
    list (
$bistag , $bismonat) = split ('.' , $todate); // << bad
   
$bisdatum = "$nowyear-$bismonat-$bistag";
   
$von = strtotime($vondatum);
   
$bis = strtotime($bisdatum);
   
$now = time();
    if ((
$now <= $bis) and ($now >= $von))
    {
        return
TRUE;
    }
    else
    {
        return
FALSE;
    }
}
?>

however this one worked perfectly

<?php
function ckdate($fromdate="01.01", $todate="31.12")
{
   
$nowyear = date("Y");
    list (
$vontag , $vonmonat) = split ('[.]' , $fromdate); // << good
   
$vondatum = "$nowyear-$vonmonat-$vontag";
    list (
$bistag , $bismonat) = split ('[.]' , $todate); // << good
   
$bisdatum = "$nowyear-$bismonat-$bistag";
   
$von = strtotime($vondatum);
   
$bis = strtotime($bisdatum);
   
$now = time();
    if ((
$now <= $bis) and ($now >= $von))
    {
        return
TRUE;
    }
    else
    {
        return
FALSE;
    }
}
?>

btw this fn checks if $now if between $fromdate and $todate
use it if you like
jeffrey at jhu dot edu
10.01.2003 22:51
In answer to gwyne at gmx dot net, dec 1, 2002:

For split(), when using a backslash as the delimiter, you have to *double escape* the backslash.

example:
==================================
<pre>
<?
$line
= 'stuff\\\thing\doodad\\';
$linearray = split('\\\\', $line); //<--NOTE USE OF FOUR(4)backslashes
print join(":", $linearray);
?>
</pre>

==================================
output is:

<pre>
stuff::thing:doodad:
</pre>
paha at paha dot hu
22.07.2002 3:51
It's evident but not mentioned in the documentation that using asterisks is more restricted than in a normal regular expression.

for exaple you cannot say:

split(";*",$string);

because what if there's no ";" separator?(which is covered by this regular expression)

so you have to use at least

split(";+",$quotatxt);

in this situation.
fotw at gmx dot net
17.06.2002 21:50
Ups! It seems that neither explode nor split REALY takes a STRING but only a single character as a string for splitting the string.
 I found this problem in one of my codes when trying to split a string using ";\n" as breaking string. The result, only ";" was thaken... the rest of the string was ignored.
 Same when I tried to substitute "\n" by any other thing. :(
not at anythingspecial dot com
17.06.2002 3:48
If you need to do a split on a period make sure you escape the period out..

$ext_arr = split("\.","something.jpg");
... because
$ext_arr = split(".","something.jpg"); won't work properly.
kang at elpmis dot com
12.06.2002 20:30
This is a good way to display a comma delimited file with two columns.  The first column is the URL's description, the second is the actual URL.

<ul>
<?php
  $fname
="relatedlinks.csv";
 
$fp=fopen($fname,"r") or die("Error found.");
 
$line = fgets( $fp, 1024 );
  while(!
feof($fp))
  {
    list(
$desc,$url,$dummy) = split( ",", $line, 3 );
    print
"<li>";
    print
"<a href='$url'>$desc</a>";
    print
"</li>\n";
   
$line = fgets( $fp, 1024 );
  }
 
fclose($fp);
?>
</ul>
jchart at sdccu dot net
31.05.2002 21:56
[Ed. note: Close. The pipe *is* an operator in PHP, but
the reason this fails is because it's also an operator
in the regex syntax. The distinction here is important
since a PHP operator inside a string is just a character.]

The reason your code:

$line = "12|3|Fred";
list ($msgid, $msgref, $msgtopic)=split('|', $line);

didn't work is because the "|" symbol is an operator in PHP. If you want to use the pipe symbol as a delimiter you must excape it with a back slash, "\|". You code should look like this:

$line = "12|3|Fred";
list ($msgid, $msgref, $msgtopic)=split('\|', $line);
mcgarry at tig dot com dot au
17.05.2002 12:27
split() doesn't like NUL characters within the string, it treats the first one it meets as the end of the string, so if you have data you want to split that can contain a NUL character you'll need to convert it into something else first, eg:

$line=str_replace(chr(0),'',$line);



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",...)