【问题标题】:PHP: preg_match_all that matches inner brackets first?PHP:preg_match_all 首先匹配内括号?
【发布时间】:2013-02-14 15:45:07
【问题描述】:

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

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

我需要一个匹配内括号对的正则表达式first,所以preg_match_all 找到匹配括号对的顺序应该是:

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

所有文本可能有所不同。

preg_match_all 甚至可以做到这一点吗?

【问题讨论】:

  • 在另一对中可以有不止一对吗?例如[foo[bar][baz][xyzzy]lol]?
  • 是的,理想情况下可能是这样。我更改了问题以包含此功能...
  • @MarcB 建议的副本想要忽略内部组,这与这个问题相反。

标签: php regex preg-match-all


【解决方案1】:

这对于正则表达式是不可能的。无论您的正则表达式多么复杂,它总是会首先返回最左边的匹配项。

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

【讨论】:

    【解决方案2】:

    在您的问题中不清楚您想要什么样的“匹配结构”......但是您只能使用简单的数组。试试

      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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-18
      相关资源
      最近更新 更多