4

I need to explode a string by commas but not within quotes(«»).

I have a string like: "5,test2,4631954,Y,«some, string, text.»,299.00 TJS,http://some-link"

i want this result:

[
 0 => 5,
 1 => test2,
 2 => 4631954,
 3 => Y,
 4 => «some, string, text.»,
 5 => 299.00 TJS,
 6 => http://some-link
]

Tried with preg_split, str_getcsv but didnt get needed result.

$res = str_getcsv($res, ',');
$res = preg_split("/(?<=\)),/", $res);

2 Answers2

4

If you have no regular quotation marks to take care of in your strings to split, you may get what you need with a SKIP-FAIL based regex:

$s = "5,test2,4631954,Y,«some, string, text.»,299.00 TJS,http://some-link";
print_r(preg_split('~«[^«»]*»(*SKIP)(*F)|\s*,\s*~', $s));

See the PHP demo

Pattern details

  • «[^«»]*»(*SKIP)(*F) - «, 0+ chars other than « and », and then » are matched, the regex engine is moved to the end of this matched text, and then the whole text is removed from the current match buffer and the engine goes on to search for the next match
  • | - or
  • \s*,\s* - a , enclosed with 0+ whitespaces

Output:

Array
(
    [0] => 5
    [1] => test2
    [2] => 4631954
    [3] => Y
    [4] => «some, string, text.»
    [5] => 299.00 TJS
    [6] => http://some-link
)
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
0
$theString = "5,test2,4631954,Y,«some, string, text.»,299.00 TJS,http://some-link";
$var_arr = array();
$j = mb_strlen($theString);
$chars = "";
for ($k = 0; $k < $j; $k++) 
{
    $char = mb_substr($theString, $k, 1);
    if($char == ","  )
    {
        if (!\preg_match("/[\«»]/", $chars)) {
            $var_arr[] =  $chars.",";
            $chars = "";
        }
        else{
            if(preg_match("/«(.*?)»/",$chars))
            {
                $var_arr[] =  $chars.",";
                $chars = "";
            }
            else
            $chars .= $char;
        }
    }
    else{
        $chars .= $char;
    }

    if( ($k + 1) == $j)
    {
        $var_arr[] =  $chars;
    }

}
print_r($var_arr);