PHP: preg_match_all that matches inner brackets first?

两盒软妹~` 提交于 2019-12-11 00:05:20

问题


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 ?


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/14878598/php-preg-match-all-that-matches-inner-brackets-first

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!