0

我对 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

如您所见,我唯一要更改的是正则表达式分隔符,当分隔符为方括号时,表达式无法正常工作。

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

提前致谢,

弗朗西斯科

4

2 回答 2

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';

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

于 2013-03-15T13:36:47.517 回答
0

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

于 2013-07-29T20:09:39.610 回答