简体   繁体   English

为什么 perl 正则表达式挂起?

[英]Why is perl regex hanging?

I have the following code (which uses a recursive regex).我有以下代码(使用递归正则表达式)。 Things seem to work fine, except at one particular place, where I have an unmatched brace.一切似乎都很好,除了在一个特定的地方,我有一个无与伦比的支架。 I'm trying to understand what exactly is causing the hang.我试图了解导致挂起的确切原因。 I have:我有:

use strict;
use warnings;
use Carp;
use Data::Dumper;

my $matchBracePtrn =    qr/(?<brace>\((?:[^()]+|(?&brace))+\))/;
my $mkVarPtrn =         qr/\$(?:\w|${matchBracePtrn})/;

# my $testString='$(a) $(a $(c)';   # OK: reports $(a) and $(c)...
# my $testString='$(foreach i,$(LIST),$(eval $(call foo,$i)))'; # OK
my $testString='$(a) $(foreach i,$(LIST),$(eval $(call foo,$i))'; #not OK!

while ($testString =~ /($mkVarPtrn)/g) {
    print "$1\n"
}

This outputs:这输出:

$(a)

and then hangs.然后挂起。 This is perl 5.22.0, in case that matters.这是 perl 5.22.0,以防万一。

The (?<brace>\\((?:[^()]+|(?&brace))+\\)) pattern causes catastrophic backtracking . (?<brace>\\((?:[^()]+|(?&brace))+\\))模式会导致灾难性的回溯

In order to fix the recursive pattern, either use a ++ possessive quantifier with [^()] , [^()]++ , or use an atomic group instead of the non-capturing group, (?>[^()]+|(?&brace))+ .为了修复递归模式,要么使用++所有格量词和[^()][^()]++ ,要么使用原子组而不是非捕获组, (?>[^()]+|(?&brace))+

So, use either of所以,使用任何一个

my $matchBracePtrn =    qr/(?<brace>\((?:[^()]++|(?&brace))+\))/;
my $matchBracePtrn =    qr/(?<brace>\((?>[^()]+|(?&brace))+\))/;

See the online demo .请参阅在线演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM