我对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
正如你所看到的,我唯一要改变的是正则表达式分隔符,当分隔符是方括号时,表达式无法正常工作。
有人可以解释为什么第二个不匹配?
提前致谢,
旧金山
答案 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)
在执行匹配之前,请尝试将[
替换为<
,将]
替换为>
(或其他类似的替换)。