Perl,动态生成的带有反斜杠元字符的regexp字符串奇怪的行为
下面是一个小的perl代码片段:Perl,动态生成的带有反斜杠元字符的regexp字符串奇怪的行为,regex,perl,Regex,Perl,下面是一个小的perl代码片段: my $n = 1; my $re_str = '\d'; my $re_str_q = '\Q1\E'; printf "re_str match: %s\n", ($n =~ /$re_str/); printf "re_str_q match: %s\n", ($n =~ /$re_str_q/); printf "direct match: %s\n", ($n =~ /\Q1\E/); 运行时产生以下输出: re_str match: 1
my $n = 1;
my $re_str = '\d';
my $re_str_q = '\Q1\E';
printf "re_str match: %s\n", ($n =~ /$re_str/);
printf "re_str_q match: %s\n", ($n =~ /$re_str_q/);
printf "direct match: %s\n", ($n =~ /\Q1\E/);
运行时产生以下输出:
re_str match: 1
re_str_q match:
direct match: 1
所以,我这里的问题是为什么第二个printf
不匹配?如果您更改
my $re_str_q = '\Q1\E'; #from
my $re_str_q = qr/\Q1\E/; #to
哪种方法是传递动态生成的正则表达式的正确方法,那么它将给出以下结果
re_str match: 1
re_str_q match: 1
direct match: 1
如果你用过
use strict;
use warnings;
你会得到警告的
Unrecognized escape \Q passed through in regex; marked by <-- HERE in m/\Q <-- HERE 1\E/ at so.pl line 9.
Unrecognized escape \E passed through in regex; marked by <-- HERE in m/\Q1\E <-- HERE / at so.pl line 9.
有关\Q引用的字符的确切定义,请参阅
\L、\U、\F和\Q可以堆叠,在这种情况下,每个都需要一个\E。例如:
say"This \Qquoting \ubusiness \Uhere isn't quite\E done yet,\E is it?";
This quoting\ Business\ HERE\ ISN\'T\ QUITE\ done\ yet\, is it?
\Q和\E都由字符串插值处理,而不是由正则表达式引擎处理。在第一行和第二行
printf
中绕过字符串插值。在Perl编程中搜索“七种翻译转义”以获得对此的讨论。它们是:\N{…}\U\U\L\L\E\Q\F
。(不要问我为什么有八个。)您使用单引号来构建“动态生成的regexp”。使用use warnings
perl将告诉您:
无法识别的转义\Q在正则表达式中传递;标记为的\Q不是正则表达式转义,它是字符串中替换的字符串转义,因此“\Q1\E”将等效于quotemeta('1')
因此,您需要使用可以插入这些序列的引号,如“”或qr/,或者调用quotemeta,而不是尝试使用字符串转义。正则表达式涉及两种转义
- 解析文本时处理的转义
- 由正则表达式引擎处理的转义
是前一种\Q..\E
是后一种\d
是两种类型\n
生成12个字符的字符串“abc\Q!@#\Edef”
abc\\@\#def
完全是一样的qq/abc\Q@#\Edef/
生成12个字符的字符串qr/abc\Q@#\Edef/
,然后将其编译为与9个字符相匹配的正则表达式模式@#defabc\\@\#def
生成13个字符的字符串'abc\Q@#\Edef'
abc\Q@#\Edef
\Q
或\E
,因此如果您最终将最后一个字符串传递给它,它将发出警告,然后它将尝试匹配11个字符abcQ@#Edef
解决办法是改变
my $re_str = '\d'; # Produces string \d
my $re_str_q = '\Q1\E\'; # Produces string \Q1\E
到
或者更好
my $re_str = qr/\d/; # Produces regex \d
my $re_str_q = qr/\Q1\E/; # Produces regex \1
详细了解
\
。+1解释\d
与\Q
,这似乎让人困惑OP@TLP,提供了一份参考文件,该文件将进一步详细解释。
my $re_str = "\\d"; # Produces string \d
my $re_str_q = "\Q1\E"; # Produces string \1
my $re_str = qr/\d/; # Produces regex \d
my $re_str_q = qr/\Q1\E/; # Produces regex \1