如果使用方括号作为分隔符,则Perl正则表达式无效。为什么?

时间:2013-03-15 13:31:54

标签: regex perl

我对Perl和正则表达式非常有经验。然而,这让我发疯,我只是找不到它的答案,我也看不出它的原因。请查看以下代码:

my $str = 'Hello[world]';

say $str =~ m/\w+\[.*?\]/ ? 'Yes' : 'No';
say $str =~ m[\w+\[.*?\]] ? 'Yes' : 'No';
say $str =~ m(\w+\[.*?\]) ? 'Yes' : 'No';

这个输出是:

Yes
No
Yes

正如你所看到的,我唯一要改变的是正则表达式分隔符,当分隔符是方括号时,表达式无法正常工作。

有人可以解释为什么第二个不匹配?

提前致谢,

旧金山

2 个答案:

答案 0 :(得分:6)

B::Deparse模块来救你:

$ perl -MO=Deparse foo.pl
my $str = 'Hello[world]';
say $str =~ /\w+\[.*?\]/u ? 'Yes' : 'No';
say $str =~ /\w+[.*?]/u ? 'Yes' : 'No';
say $str =~ /\w+\[.*?\]/u ? 'Yes' : 'No';
foo.pl syntax OK

正如您所看到的,在您的正则表达式中[ ]的转义意味着perl现在将它们解释为元字符,而不是分隔符。你需要两个级别的逃脱。我不确定甚至可以这样做,因为\\将被解释为字面反斜杠。

要清楚:在正常的正则表达式中,括号[]具有元字符状态。所以为了按字面意思匹配它们,它们需要被转义。当将它们用作分隔符时,您向其添加另一个元字符状态:它们也是分隔符。因此,两个元字符状态都需要转义。

这将按预期工作:

say $str =~ m[\w+\Q\[\E.*?\Q\]\E] ? 'Yes' : 'No';

当然,这里的教训是明智地选择你的分隔符。

答案 1 :(得分:0)

在执行匹配之前,请尝试将[替换为<,将]替换为>(或其他类似的替换)。