正则表达式模式在花括号之间获取字符串

时间:2015-04-27 03:35:18

标签: php regex pcre

我有一个字符串The quick brown {fox, dragon, dinosaur} jumps over the lazy {dog, cat, bear, {lion, tiger}}.

我想获得大括号之间的所有字符串。必须忽略花括号内的花括号。 PHP数组中的预期输出为

[0] => fox, dragon, dinosaur
[1] => dog, cat, bear, {lion, tiger}

我尝试了来自Regex pattern extract string between curly braces and exclude curly braces的这个模式\{([\s\S]*)\},但是看起来这个模式在花括号之间得到所有字符串而不分割非相关文本(不确定要使用的正确单词)。 这是上面模式的输出

fox, jumps, over} over the lazy {dog, cat, bear, {lion, tiger}}

打印上述句子中预期输出的最佳正则表达式是什么?

2 个答案:

答案 0 :(得分:4)

您可以在PHP中使用此递归正则表达式模式:

$re = '/( { ( (?: [^{}]* | (?1) )* ) } )/x'; 
$str = "The quick brown {fox, dragon, dinosaur} jumps over the lazy {dog, cat, bear, {lion, tiger}}."; 

preg_match_all($re, $str, $matches);
print_r($matches[2]);

RegEx Demo

答案 1 :(得分:1)

正如anubhava所说,你可以使用递归模式来做到这一点。

然而,他的版本相当慢,而且并不适用于所有情况。

我个人使用这个正则表达式:

#({(?>[^{}]|(?0))*?})#

正如你在那里看到的那样:http://lumadis.be/regex/test_regex.php?id=2516它的速度更快;并匹配更多结果。

那么,它是如何运作的?

/
  (              # capturing group
    {            # looks for the char '{'
    (?>          # atomic group, engine will never backtrack his choice
        [^{}]    #   looks for a non-'{}' char
      |          # or
        (?0)     #   re-run the regex in a subroutine to match a subgroup
    )*?          # and does it as many time as needed
    }            # looks for the char '}'
  )              # ends the capture
/x

为什么我使用" *?"

添加'?'到' *'让它不贪心。如果你在那里使用一个贪婪的量词,那么引擎将比一个不合理的量子启动更多的子程序。 (如果您需要更多解释,请告诉我们)