Bhaskar Dabhi
Bhaskar Dabhi

Reputation: 909

Explode string with comma when comma is not inside any brackets

I have string "xyz(text1,(text2,text3)),asd" I want to explode it with , but only condition is that explode should happen only on , which are not inside any brackets (here it is ()).

I saw many such solutions on stackoverflow but it didn't work with my pattern. (example1) (example2)

What is correct regex for my pattern?

In my case xyz(text1,(text2,text3)),asd

result should be

xyz(text1,(text2,text3)) and asd.

Upvotes: 3

Views: 71

Answers (2)

bobble bubble
bobble bubble

Reputation: 18535

If the requirement is to split at , but only outside nested parenthesis another idea would be to use preg_split and skip the parenthesized stuff also by use of a recursive pattern.

$res = preg_split('/(\((?>[^)(]*(?1)?)*\))(*SKIP)(*F)|,/', $str);

See this pattern demo at regex101 or a PHP demo at eval.in

The left side of the pipe character is used to match and skip what is inside the parenthesis.
On the right side it will match remaining commas that are left outside of the parenthesis.

The pattern used is a variant of different common patterns to match nested parentehsis.

Upvotes: 1

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627082

You may use a matching approach using a regex with a subroutine:

preg_match_all('~\w+(\((?:[^()]++|(?1))*\))?~', $s, $m)

See the regex demo

Details

  • \w+ - 1+ word chars
  • (\((?:[^()]++|(?1))*\))? - an optional capturing group matching
    • \( - a (
    • (?:[^()]++|(?1))* - zero or more occurrences of
      • [^()]++ - 1+ chars other than ( and )
      • | - or
      • (?1) - the whole Group 1 pattern
    • \) - a ).

PHP demo:

$rx = '/\w+(\((?:[^()]++|(?1))*\))?/';
$s = 'xyz(text1,(text2,text3)),asd';
if (preg_match_all($rx, $s, $m)) {
    print_r($m[0]);
}

Output:

Array
(
    [0] => xyz(text1,(text2,text3))
    [1] => asd
)

Upvotes: 1

Related Questions