我刚刚读了关于Q
和E
,我试图完全理解它们。根据Perlre的说法:
\Q 引号(禁用)模式元字符,直到 \E
\E 结束大小写修改或引用部分,思考 vi
所以我做了几个测试:
$ perl -e 'print "hellon" if "he\tllo" =~ /Qt/'
hello
$ perl -e 'print "hellon" if "he\tllo" =~ /t/'
$
如果我理解正确,如果没有Q
它就不会评估为 True,因为它t
视为一个选项卡。
然后我用了E
,我看不出有什么区别:
$ perl -e 'print "hellon" if "he\tllo" =~ /QtE/'
hello
如果我给出一个更广泛的字符串和模式,其中包含文字t
和一个制表符:
$ perl -e 'print "hellon" if "he\tltlo" =~ /QtE.*t/'
hello
它似乎有效,因为它将第一个t
视为固定字符串,而第二个t
被视为制表符。
那么这是Q
和E
应该使用的方式吗?也就是说,我们是否将"干净"字符串括在Q
和E
之间?如果一切都应该被视为文字,那么只使用Q
是否正确?
E
标志着结束,不仅是Q
,还有其他转义,例如U
。因此,当您需要结束Q
序列时,您将使用它。但我认为你想多了。 Q
是quotemeta()
的逃生版本。
"(foobar" =~ /Q(fo+bar/ # false, "+" gets escaped
"(foobar" =~ /Q(Efo+bar/ # true
我不会说"应该使用"。如果您不使用E
,则Q
会贯穿整个模式。
查看E
如何工作的更切实的方法是将其与U
一起使用:
$ perl -lwe' print "Ufoobar" '
FOOBAR
$ perl -lwe' print "UfooEbar" '
FOObar
就像"abc $x def"
一样"abc ".$x." def"
$ diff -u0
<( perl -MO=Concise,-exec -E'$_ = "abc $x def";' 2>&1 )
<( perl -MO=Concise,-exec -E'$_ = "abc ".$x." def";' 2>&1 )
&& echo "same"
same
"abc Q$xtE def"
与"abc ".quotemeta($x."t")." def"
相同
$ diff -u0
<( perl -MO=Concise,-exec -E'$_ = "abc Q$xtE def";' 2>&1 )
<( perl -MO=Concise,-exec -E'$_ = "abc ".quotemeta($x."t")." def";' 2>&1 )
&& echo "same"
--- /dev/fd/63 2015-01-06 11:22:49.564061341 -0500
+++ /dev/fd/62 2015-01-06 11:22:49.564061341 -0500
@@ -7,3 +7,3 @@
-6 <2> concat[t3] sK/2
-7 <1> quotemeta[t4] sK/1
-8 <2> concat[t5] sK/2
+6 <2> concat[t4] sK/2
+7 <1> quotemeta[t5] sK/1
+8 <2> concat[t6] sK/2
@@ -11 +11 @@
-a <2> concat[t6] sKS/2
+a <2> concat[t7] sKS/2
(差异只是"pad"(存储词汇的数组)中索引的差异。
它也可以在正则表达式文本中使用。
my $exact_text = "...";
my $pat = quotemeta($exact_text);
if (/$pat/) { ... }
是长
my $exact_text = "...";
if (/Q$exact_textE/) { ... }
如果E
位于文字的末尾,则可以省略。
my $exact_text = "...";
if (/Q$exact_text/) { ... }
如果没有危险,则不需要最后的E
。我不确定这种行为是否被记录下来,但我已经看过很多次了。
看看变量插值如何与Q
一起发挥作用也很有趣:
perl -E '$x = "lo$"; say "hello" =~ /$x/'
1
perl -E '$x = "lo$"; say "hello" =~ /Q$x/'
# ^
# | empty line here.
另请参阅引用元。