Reputation: 9383
In PHP I have string with nested brackets:
bar[foo[test[abc][def]]bar]foo
I need a regex that matches the inner bracket-pairs first, so the order in which preg_match_all
finds the matching bracket-pairs should be:
[abc]
[def]
[test[abc][def]]
[foo[test[abc][def]]bar]
All texts may vary.
Is this even possible with preg_match_all
?
Upvotes: 2
Views: 963
Reputation: 13940
Is not evident in your question what kind of "structure of matches" you whant... But you can use only simple arrays. Try
preg_match_all('#\[([a-z\)\(]+?)\]#',$original,$m);
that, for $original = 'bar[foo[test[abc][def]]bar]foo'
returns an array with "abc" and "def", the inner ones.
For your output, you need a loop for the "parsing task". PCRE with preg_replace_callback is better for parsing.
Perhaps this loop is a good clue for your problem,
$original = 'bar[foo[test[abc][def]]bar]foo';
for( $aux=$oldAux=$original;
$oldAux!=($aux=printInnerBracket($aux));
$oldAux=$aux
);
print "\n-- $aux";
function printInnerBracket($s) {
return preg_replace_callback(
'#\[([a-z\)\(]+?)\]#', // the only one regular expression
function($m) {
print "\n$m[0]";
return "($m[1])";
},
$s
);
}
Result (the callback print):
[abc]
[def]
[test(abc)(def)]
[foo(test(abc)(def))bar]
-- bar(foo(test(abc)(def))bar)foo
See also this related question.
Upvotes: 0
Reputation: 19661
This is not possible with regular expressions. No matter how complex your regex, it will always return the left-most match first.
At best, you'd have to use multiple regexes, but even then you're going to have trouble because regexes can't really count matching brackets. Your best bet is to parse this string some other way.
Upvotes: 2