Reputation: 909
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
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
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 )
.$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