regex - 为什么 Perl 正则表达式挂起?

标签 regex perl

我有以下代码(使用递归正则表达式)。一切似乎都很顺利,除了在一个特定的地方,我有一个无与伦比的支架。我试图了解到底是什么导致了挂起。我有:

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"
}

输出:

$(a)

然后挂起。这是 perl 5.22.0,以防万一。

最佳答案

(?<brace>\((?:[^()]+|(?&brace))+\))模式原因catastrophic backtracking .

为了修复递归模式,可以使用 ++所有格量词 [^()] , [^()]++ ,或使用原子组代替非捕获组,(?>[^()]+|(?&brace))+ .

因此,使用其中之一

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

请参阅online demo .

关于regex - 为什么 Perl 正则表达式挂起?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60305714/

相关文章:

perl - 使用 csv 文件复制/重命名带有 utf8 名称的图像

linux - 尝试在 web min 中创建新用户和更新用户时出错

perl - 如何确定 Perl 中变量的值是标量还是数组?

java - 将 php 正则表达式转换为 java 正则表达式

java - 用于获取包含引号的字符串的正则表达式

javascript - 从句子中删除停用词

perl - 这个 Perl Map 调用在做什么?

java - 模式和匹配器java问题

java - 字符串中的模式

perl - 如何摆脱 `Wide character in print at` ?