花括号中间的字符串的正则表达式模式

3

我有一个字符串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}

我尝试了这个模式\{([\s\S]*)\},来自Mar在StackOverflow上的回答。但是似乎这个模式获取花括号之间的所有字符串而不分割无关的文本(不确定该使用什么词)。下面是该模式的输出结果。

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

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

可能是What does the "[^][]" regex mean?的重复问题。 - HamZa
有很多重复的内容,但是对于链接的重复问题提供的答案据我所知是最好的,因为它提供了递归技术的深入解释。 - HamZa
这里有另一个有趣的答案:链接 - HamZa
请大家帮我回答我的问题,链接为http://stackoverflow.com/questions/33841196/how-to-match-text-inside-starting-and-closing-curly-brace-the-tags-and-the-spec。谢谢! - WebICT By Leo
请参考这里的类似问题:http://stackoverflow.com/questions/33841196/how-to-match-text-inside-starting-and-closing-curly-brace-the-tags-and-the-spec - WebICT By Leo
2个回答

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]);

正则表达式演示


1
非常感谢。你救了我的一天 :) - valrecx
-01 这里有很多重复的内容,而且这个答案甚至没有解释原理。 - HamZa

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

为什么我要使用"*?"

在星号后加上问号可以使其变成非贪婪模式。如果你使用贪婪量词,引擎将会比使用非贪婪量词时启动更多的子程序。 (如果需要更多解释,请告诉我)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接