为什么使用这些简单的Regexp时,Regexp::Assemble会失败?

为什么使用这些简单的Regexp时,Regexp::Assemble会失败?,regex,perl,Regex,Perl,我在我的项目中使用了,但我不明白为什么这个小示例不起作用: #!/usr/bin/perl use strict; use warnings; use Regexp::Assemble; my $re1 = "(run (?:pre|post)flight script for .+)"; my $re2 = "((?:Configu|Prepa)ring volume .+)"; my $ra = Regexp::Assemble->new; $ra->add($re1

我在我的项目中使用了,但我不明白为什么这个小示例不起作用:

#!/usr/bin/perl

use strict;
use warnings;

use Regexp::Assemble;

my $re1 = "(run (?:pre|post)flight script for .+)";
my $re2 = "((?:Configu|Prepa)ring volume .+)";

my $ra   = Regexp::Assemble->new;
$ra->add($re1);
$ra->add($re2);
my $global = $ra->re;

print "GLOBAL: $global\n";

1;
我得到了这个错误:

Unmatched ( in regex; marked by <-- HERE in m/( <-- HERE ?:(run (?:pre|post)flight script for|((?:Configu|Prepa)ring volume) .+)/ at /usr/share/perl5/Regexp/Assemble.pm line 1003.

缺少一个…

这看起来像个bug?您混淆了正则表达式构造函数。看看它是如何将两种模式结合在一起并使括号不匹配的:

my $re1 =     "(run (?:pre|post)flight script for .+)";
my $re2 =                                        "((?:Configu|Prepa)ring volume .+)";

#         m/(?:(run (?:pre|post)flight script for|((?:Configu|Prepa)ring volume) .+)/ at...
尝试从正则表达式中删除额外的括号集,看看这是否有帮助:

my $re1 = "run (?:pre|post)flight script for .+";
my $re2 = "(?:Configu|Prepa)ring volume .+";

这看起来像个虫子?您混淆了正则表达式构造函数。看看它是如何将两种模式结合在一起并使括号不匹配的:

my $re1 =     "(run (?:pre|post)flight script for .+)";
my $re2 =                                        "((?:Configu|Prepa)ring volume .+)";

#         m/(?:(run (?:pre|post)flight script for|((?:Configu|Prepa)ring volume) .+)/ at...
尝试从正则表达式中删除额外的括号集,看看这是否有帮助:

my $re1 = "run (?:pre|post)flight script for .+";
my $re2 = "(?:Configu|Prepa)ring volume .+";

乙醚的方法似乎是一个计划——如果您查看它特别提到的模块文档,请注意:


加上。。。它使用一个简单的正则表达式对可能被复杂表达式愚弄的字符串进行lex。具体来说,它将无法正确地lex嵌套的插入式表达式,如abcdef?ghij。如果是这种情况,字符串的结尾将不会被正确标记并作为一个长字符串返回。

以太的方法似乎是一个计划-如果您查看它特别提到的模块文档,请注意:


加上。。。它使用一个简单的正则表达式对可能被复杂表达式愚弄的字符串进行lex。具体来说,它将无法正确地lex嵌套的插入式表达式,如abcdef?ghij。如果是这种情况,字符串的结尾将不会被正确标记并作为一个长字符串返回。

我是R::A的作者。这个问题每隔几年就会出现一次。其想法是,您不想添加复杂的父化模式。添加更多、更简单的模式,例如

run preflight script for .+
run postflight script for .+
Configuring volume .+
Preparing volume .+
不要尝试做模块的工作。例如,您的过早分组导致所有模式的尾随.+公共值在regexp中没有被分解成一个事件。结果是引入了不必要的回溯。你添加的模式越多,情况就越糟

以不同的顺序调用add将产生相同的结果模式,否则我想知道这是一个bug


否则,您可以自己对模式进行预处理,并使用insert将模式词素直接插入到用于构建模式的内部trie结构中。这将要快得多,因为lexer非常慢:组装一个模式需要消耗一半以上的运行时间。

我是R::a的作者。这个问题每隔几年就会出现一次。其想法是,您不想添加复杂的父化模式。添加更多、更简单的模式,例如

run preflight script for .+
run postflight script for .+
Configuring volume .+
Preparing volume .+
不要尝试做模块的工作。例如,您的过早分组导致所有模式的尾随.+公共值在regexp中没有被分解成一个事件。结果是引入了不必要的回溯。你添加的模式越多,情况就越糟

以不同的顺序调用add将产生相同的结果模式,否则我想知道这是一个bug


否则,您可以自己对模式进行预处理,并使用insert将模式词素直接插入到用于构建模式的内部trie结构中。这将要快得多,因为lexer非常慢:它在组装模式时消耗了一半以上的运行时间。

是的,它在没有额外括号的情况下工作。。。但这里只有一个例子,我需要在更复杂的regexp中使用它们!好吧,这回答了你写的问题…:也许可以编辑你的问题,给出一个如此复杂的例子?好吧,我应该补充一下,我如何在不修改regexp的情况下解决这个问题:有什么想法吗?根据martin clayton的引用,我怀疑你可能需要修改你的regexp。您是否可以以不同的方式编写它们或以不同的顺序调用add?是的,它在没有额外括号的情况下工作。。。但这里只有一个例子,我需要在更复杂的regexp中使用它们!好吧,这回答了你写的问题…:也许可以编辑你的问题,给出一个如此复杂的例子?好吧,我应该补充一下,我如何在不修改regexp的情况下解决这个问题:有什么想法吗?根据martin clayton的引用,我怀疑你可能需要修改你的regexp。你能不能以不同的方式组合它们或以不同的顺序调用add?好的,谢谢,你回答了“为什么”,但我也对“我如何解决这个问题”感兴趣:好的,谢谢,你回答了“为什么”,但我也对“我如何解决这个问题”感兴趣:当我组装上述四种模式时,我获取?:运行p?:ost |为|?:Configu |准备卷的反射脚本。注意模块是如何将“p”从post | pre alternation中提升出来的?当我组装上述四种模式时,我得到了?:run p?:ost | reflight script for |?:Configu | Preparing volume.+。注意模块是如何将“p”吊出立柱的?预更换?