正如 ikegami 所说,需要这么长时间的原因是模式可以将字符串分成块的方式呈指数级增长。为了让它在 Perl 的正则表达式引擎中有效地工作,你必须限制回溯。
您可以使用++
所有格量词来做到这一点。这通过说它是全部或全部来限制回溯。但要让它发挥作用,你必须小心它匹配的内容。
不起作用的原因[^()]++
(您不需要那里的反斜杠,括号在字符类中并不特殊)是它也匹配|
,这是您更大的正则表达式正在寻找的字符。您需要能够回溯|
,但不能回溯其他字符(因为将字符串拆分为除(
)
或|
不会帮助正则表达式匹配的字符)。
尝试这个:
$BRACE_MATCH = qr/ (?: [^()|]++ | \| | \((??{$BRACE_MATCH})\))* /x;
这表示这$BRACE_MATCH
是任意数量的 3 件事的序列:
- 字符串以外的字符
()|
(将作为单个块回溯)
- 一个
|
字符
- 平衡的
(...)
表达
原因是
$BRACE_MATCH = qr/ (?: [^()]++ | \((??{$BRACE_MATCH})\))* /x;
不匹配(XX || YY) || ZZ
的是 . 后面有空格)
。该空格与该[^()]++
部分匹配,但也与字符串的其余部分匹配(因为没有更多的括号),然后不会将其部分返回(因为它是所有格量词)。