如果*FOO
(*作为普通字符)这样的单词在一行中,我会尝试匹配。我的输入是C ++源代码。由于程序流程要求,我需要使用预编译的正则表达式,所以我尝试了以下内容:
$pattern = qr/[^a-zA-Z](\*FOO)[^a-zA-Z]|^\s*(\*FOO)[^a-zA-Z]/;
我这样使用它:
if ($line =~ m/$pattern/) { ... }
它有效并捕获包含*FOO
的行,例如hey *FOO.BAR
,但也匹配以下行:
//FOO programming using stuff and things
我想忽略。我错过了什么? \*
不是在perl中预先编译的正则表达式中转义*
的正确方法吗?如果*FOO
存储在$word
中且模式如下:
$pattern = qr/[^a-zA-Z](\\$word)[^a-zA-Z]|^\s*(\\$word)[^a-zA-Z]/;
这与之前的模式不同吗?因为我试过两个,结果似乎是一样的。
我找到了一种绕过此问题的方法,删除了$word
中的第一个字符并在模式中转义*
,但如果$word = "**.?FOO"
例如,我该如何创建{{ 1}}使用qr//
以便所有元字符都被转义?
答案 0 :(得分:1)
my $word = '*FOO';
my $pattern = qr/\\$word/;
相当于
my $pattern = qr/\\*FOO/; # zero or more '\' followed by 'FOO'
$word
只是按原样插值。
获得与
等效的东西my $pattern = qr/\*FOO/;
你应该使用
my $word = '*FOO';
my $pattern = qr/\Q$word\E/;
默认情况下,插值变量被视为迷你正则表达式,变量中的元字符(如*
,+
,?
仍被解释为元字符。 \Q...\E
会在任何不匹配/[A-Za-z_0-9]/
的字符之前添加反斜杠,因此插值变量中的任何元字符都会被解释为文字字符。请参阅perldoc。
我试过
my $pattern = qr/[^a-zA-Z](\*FOO)[^a-zA-Z]|^\s*(\*FOO)[^a-zA-Z]/;
my $line = '//FOO programming using stuff and things';
if($line =~ m/$pattern/){
print "$&\n";
}
else{
print "No match!";
}
它打印了#34;不匹配!"。我无法解释你是如何匹配它的。
答案 1 :(得分:1)
你需要逃避*
。一种方法是quotemeta
use warnings;
use strict;
my $qr = /\Q*FOO/;
while (<DATA>) { print if /$qr/ }
__DATA__
//FOO programming using stuff and things
hey *FOO.BAR
这确定*FOO
是否在行中,无论它是单词还是单词的一部分。我不清楚问题是什么情况。一旦指定,就可以调整模式。
请注意,/\*FOO/
也有效。你尝试失败的原因可能是因为你想要匹配的其余部分,我不明白的目的。如果您只需要检测模式是否存在,则上述操作。如果有更具体的要求请澄清。