PHP:preg_match_all首先匹配内部括号?

时间:2013-02-14 15:45:07

标签: php regex preg-match-all

在PHP中,我有带嵌套括号的字符串:

bar[foo[test[abc][def]]bar]foo

我需要一个与内部括号对匹配的正则表达式,因此preg_match_all找到匹配的括号对的顺序应为:

[abc]
[def]
[test[abc][def]]
[foo[test[abc][def]]bar]

所有文字可能会有所不同。

preg_match_all是否可以实现这一点?

2 个答案:

答案 0 :(得分:2)

正则表达式无法做到这一点。无论你的正则表达式多么复杂,它总会首先返回最左边的匹配。

充其量,您必须使用多个正则表达式,但即使这样,您也会遇到麻烦,因为正则表达式无法真正计算匹配括号。你最好的办法是以其他方式解析这个字符串。

答案 1 :(得分:0)

你的问题中没有明显的是你想要什么样的“匹配结构”......但是你只能使用简单的数组。尝试

  preg_match_all('#\[([a-z\)\(]+?)\]#',$original,$m); 

对于$original = 'bar[foo[test[abc][def]]bar]foo',返回一个带有“abc”和“def”的数组,内部的数组。


对于您的输出,您需要一个“解析任务”的循环。 具有preg_replace_callback的PCRE更适合解析。

也许这个循环是你问题的一个很好的线索,

 $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
    );
 }

结果(回调打印):

[abc]
[def]
[test(abc)(def)]
[foo(test(abc)(def))bar]
-- bar(foo(test(abc)(def))bar)foo

另见this related question