我首先发布了这个问题: Regex matching nested beginning and ending tags
WiktorStribiżew完美地回答了这个问题。现在,我想升级我的Regex表达式,以便我的参数支持JSON对象(或者差不多,因为孤独的'{'和'['不受支持)。
我有两个表达式:一个用于配对标签,一个用于孤独的标签。我首先使用配对的,当所有替换完成后,我执行孤独的一个。修改过的孤独的一个在regex101.com(https://www.regex101.com/r/HIEQZk/9)上工作得很好,但配对的告诉我“castatrophic backtracking”(https://www.regex101.com/r/HIEQZk/8),即使在PHP中没有崩溃。
所以任何人都可以帮我优化/修复这个相当庞大的正则表达式。 即使似乎无用的转义,也是因为开始/结束标记和分割器可以自定义,因此必须进行转义。 (配对的不是因为它不是由PHP生成的那个,而是由WiktorStribiżew根据我的修改生成的那个。)
我认为应该优化/修复的唯一部分是我刚刚修改为支持JSON对象的“参数”组。 (在相同的regex101 url的早期版本中可以看到这些测试。这里有一个真正的HTML要解析。)
孤独的表达
~
\{\{ #Instruction start
([^\^\{\}]+) # (Group 1) Instruction name OR variable to reach if nothing else after then
(?:
\^
(?:([^\\^\{\}]*)\^)? #(Group 2) Specific delimiter
([^\{\}]*{(?:[^{}\[\]]+|(?3))+}[^\{\}]*|[^\{\}]*\[(?:[^{}\[\]]+|(?3))+\][^\{\}]*|[^\{\}]+) # (Group 3) Parameters
)?
\}\} #Instruction end
~xg
配对表达
~{{ # Opening tag start
(\w+) # (Group 1) Tag name
(?: # Not captured group for optional parameters
(?: # Not captured group for optional delimiter
\^ # Aux delimiter
([^^\{\}]?) # (Group 2) Specific delimiter
)?
\^ # Aux delimiter
([^\{\}]*{(?:[^{}\[\]]+|(?3))+}[^\{\}]*|[^\{\}]*\[(?:[^{}\[\]]+|(?3))+\][^\{\}]*|[^\{\}]+) # (Group 3) Parameters
)?
}} # Opening tag end
( # (Group 4)
(?>
(?R) # Repeat the whole pattern
| # or match all that is not the opening/closing tag
[^{]*(?:\{(?!{/?\1[^\{\}]*}})[^{]*)*
)* # Zero or more times
)
{{/\1}} # Closing tag
~ix
答案 0 :(得分:1)
尝试使用(?:
atomic groups替换您的(?>
非捕获组,以尽可能防止/减少回溯。那些也是非捕获的。和/或在regex101中观看stepscounter / debugger时试用possessive quantifiers。
无论您何时不希望引擎返回并尝试其他不同的方式。
This is your updated demo我刚刚将第一个(?:
更改为(?>