为什么Perl抱怨\Q..\E regex节中的括号不匹配?
我在一个变量中有一个正则表达式,它在为什么Perl抱怨\Q..\E regex节中的括号不匹配?,regex,perl,Regex,Perl,我在一个变量中有一个正则表达式,它在\Q..\E中包含一个子字符串,其中包含一个左括号。我希望解析器将[解释为普通字符,因为它位于\Q..\E节中 当正则表达式作为文本出现在程序中时,似乎就是这种情况,但当它出现在变量中时,解析器就失败了 这里有一个简化的例子 这项工作: $r = qr/\Qa[b\E\d+/; if ("a[b1" =~ $r) { print "match\n"; } 这失败了: $v='\Qa[b\E\d+'; $r=qr/$v/; 它在2号线死了 无与伦比的[在正则
\Q..\E
中包含一个子字符串,其中包含一个左括号。我希望解析器将[
解释为普通字符,因为它位于\Q..\E
节中
当正则表达式作为文本出现在程序中时,似乎就是这种情况,但当它出现在变量中时,解析器就失败了
这里有一个简化的例子
这项工作:
$r = qr/\Qa[b\E\d+/;
if ("a[b1" =~ $r) { print "match\n"; }
这失败了:
$v='\Qa[b\E\d+';
$r=qr/$v/;
它在2号线死了
无与伦比的[在正则表达式中;标记为的Perl正则表达式首先被当作一个简单的双引号字符串进行求值。任何嵌入变量都会被插值,而非源自插值变量的转义序列都会被处理。这就是像
\L
、\U
和\Q...E
这样的特殊运算符是继续
处理在双引号字符串中停止,但在正则表达式中,该字符串随后被编译
在你的例子中,你有
$v = '\Qa[b\E\d+';
因为您使用了单引号,所以这个字符串根本没有改变
然后使用
$r = qr/$v/;
但是,由于插值变量内的转义序列未被触及,因此字符串会按原样传递给正则表达式编译器,该编译器会报告该表达式无效,因为它包含一个不匹配的未转义的开括号。如果删除该括号,仍然会出现错误;这次是未识别的转义\Q在中传递regex
显示\Q..\E
未被处理并显示为文本
工作方法是将作业更改为$v
,改为使用双引号,如下所示
my $v = "\Qa[b\E\\d+";
必须将
\d
上的反斜杠加倍,否则is将消失。现在\Q..\E
已生效,$v
等于a\[b\d+
。将其编译为正则表达式很好。\Q
与正则表达式无关。当正则表达式引擎看到\Q
时,它不识别它,发出警告,并将其视为\\Q
>perl -we"$re='\Qa'; qr/$re/
Unrecognized escape \Q passed through in regex; marked by <-- HERE in m/\Q <-- HERE a/ at -e line 1.
解决方案:
$v=“\Qa[b\E\\d+”;
$v=qr/\Qa[b\E\d+/;
$v=quotemeta('a[b')。\d+';
$v=qr/\Qa[b\E\d+/;
print "$v\n";
输出为:
(?-xism:a\[b\d+)
请注意,\Q和\E已消失,括号已转义。如果您分配的字符串在单引号内分别包含\Q和\E:
$v='ab\Qcd\Eef';
$r=qr/$v/;
print "$r\n";
你会得到:
(?-xism:ab\Qcd\Eef)
此正则表达式实际上与“abQcdEef”匹配:
结果:
matches
@ikegami:你说得对,但是你的代码没有演示它,因为变量内的转义序列始终没有被触及。这个
perl-E“表示qr/\t/,qr/\x09/,qr/\n/,qr/\x0A/”
确实如此,我很惊讶,因为它意味着正则表达式的双引号处理与标准字符串的处理不同。(“\t”eq“\x09”
但是qr/\t/ne qr/\x09/
)如果你想让正则表达式引擎能够理解像\t
这样的东西,你最好还是让\t
保持可读性。OTOH,\N{…}
被转换成\N{U+…}
,如果你使用用户定义的名字。perl-Mcharnames=:full-E“说qr/\N{带锐音符的拉丁文小写字母E}/“
我从这个答案中了解到,我试图处理的正则表达式是错误的。我无法更改它,它是我的代码中的一个变量。我问题的前提是,\Q..\E
是一个正则表达式语法构造。因为它一开始就错了,所以问题的其余部分没有意义。谢谢你的解释。@Daniel Vér是的,严格。
$v='ab\Qcd\Eef';
$r=qr/$v/;
if("abQcdEef" =~ /$r/) {print "matches\n"} else {print "no match\n"}
matches