Reputation: 1129
I'm trying to match the following array-like pattern with regex:
foo[bar][baz][bim]
I almost have it with the following regex:
~([^[]+)(?:\[(.+?)\])*~gm
However, the capturing groups only include:
Full match: foo[bar][baz][bim]
Group 1: foo
Group 2: bim
I can't figure out why it's only capturing the last occurrence of the []
structure. I'd like it capture foo, bar, baz, and bim in this case.
Any ideas on what I'm missing?
Upvotes: 2
Views: 199
Reputation: 23958
This can also be parsed without regex.
Remove the closing ]
and then explode on the opening [
.
$str = "foo[bar][baz][bim]";
$str = str_replace("]","",$str);
$arr = explode("[", $str);
var_dump($arr);
Returns:
array(4) {
[0]=>
string(3) "foo"
[1]=>
string(3) "bar"
[2]=>
string(3) "baz"
[3]=>
string(3) "bim"
}
Where the first item is the "array" name and the following is the children/path.
Upvotes: 1
Reputation: 48741
Repeated capturing groups in PCRE don't remember the values of each previous pattern. For this you need to invoke \G
token:
(?|(\w+)|\G(?!\A)\[([^][]*)\])
See live demo here
Regex breakdown:
(?|
Start of a branch reset group
(\w+)
Capture word characters|
Or\G(?!\A)
Conitnue from where previous match ends\[
Match an opening bracket([^][]*)
Capture any thing except [
and ]
\]
Match a closing bracket)
End of clusterPHP code:
preg_match_all('~(?|(\w+)|\G(?!\A)\[([^][]*)\])~', 'foo[bar][baz][bim]', $matches);
print_r($matches[1]);
Upvotes: 2