Explode string when not between ()
Asked Answered
S

2

6

I'm trying to explode an string by comma's: , but only when it's not between parenthesis (...)

Here's some code to show what I mean:

$string = "K.VisueelNr,IFNULL(P.Partijnaam, 'Leeg gemeld') AS Partijnaam,R.Ras,M.Maat,DATE_FORMAT(KS.Timestamp, '%d-%c-%Y') AS Datum,H.Handelshuis,KS.Actie";

print_r(str_getcsv($string, '()'));

print_r(explode(",", $string));

Which will output:

Array
(
    [0] => K.VisueelNr,IFNULL
    [1] => P.Partijnaam, 'Leeg gemeld') AS Partijnaam,R.Ras,M.Maat,DATE_FORMAT
    [2] => KS.Timestamp, '%d-%c-%Y') AS Datum,H.Handelshuis,KS.Actie
)
Array
(
    [0] => K.VisueelNr
    [1] => IFNULL(P.Partijnaam
    [2] =>  'Leeg gemeld') AS Partijnaam
    [3] => R.Ras
    [4] => M.Maat
    [5] => DATE_FORMAT(KS.Timestamp
    [6] =>  '%d-%c-%Y') AS Datum
    [7] => H.Handelshuis
    [8] => KS.Actie
)

But I'm looking for an output like this:

Array
(
    [0] => K.VisueelNr
    [1] => IFNULL(P.Partijnaam, 'Leeg gemeld') AS Partijnaam
    [2] => R.Ras
    [3] => M.Maat
    [4] => DATE_FORMAT(KS.Timestamp, '%d-%c-%Y') AS Datum
    [5] => H.Handelshuis
    [6] => KS.Actie
)

Here's an PHP Sandbox fiddle to play around

Maybe it has to be done with preg_split, but I don't know how the regex would look like then...

Sumerlin answered 25/6, 2015 at 5:44 Comment(0)
H
8

You need to use preg_split which splits the input according to the given regex.

$words = preg_split('~,(?![^()]*\))~', $str);
print_r($words);

DEMO

Explanation:

  • , matches all the commas, only if it's not
  • followed by any char but not of ( or ), zero or more times
  • and further followed by a closing bracket.

If you change (?! to (?=, it does the opposite of matching all the commas which are present inside the brackets.

Hallvard answered 25/6, 2015 at 5:46 Comment(4)
Thank you very much. Its works indeed as expected. And thank you very much for the demo link also. The information provided by the explanation is very helpfullSumerlin
@Sumerlin Note that this method is very fragile. It breaks when there are nested function calls.Wakefield
@Wakefield luckily that's not the case. But now I'm curious. Can you point me to somewhere with an explanation for this problem?Sumerlin
@Mathlight: Here is an example func(arg1, func(arg2)) as field. You can't expect it to work correctly in general when you only look at some characters in front of a ,.Wakefield
B
0

Needed a solution that works with nested brackets and came up with this:

$delimiter = ',';
$string = "K.VisueelNr,IFNULL(P.Partijnaam, 'Leeg gemeld') AS Partijnaam,func(arg1, func(arg2)) as field";

$array = explode($delimiter, $string);
$new_array = [];
$helper_string = '';
$count1 = 0;
$count2 = 0;
foreach ($array as $str) {
    $count1 += substr_count($str, '(');
    $count2 += substr_count($str, ')');
    if (strlen($helper_string) > 0) {
        $helper_string .= $delimiter;
    }
    $helper_string .= $str;
    if ($count1 === $count2) {
        $new_array[] = $helper_string;
        $helper_string = '';
        $count1 = 0;
        $count2 = 0;
    }
}
// Fallback in case of broken brackets
if (strlen($helper_string)) {
    $new_array[] = $helper_string;
}
print_r($new_array);

Result:

Array
(
    [0] => K.VisueelNr
    [1] => IFNULL(P.Partijnaam, 'Leeg gemeld') AS Partijnaam
    [2] => func(arg1, func(arg2)) as field
)
Butlery answered 6/11, 2020 at 8:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.