Perl 中的 \Q 是什么?总是需要使用 \E 吗?
What is \Q in Perl? Is it always necessary to use \E?
我刚刚阅读了有关 \Q
和 \E
的内容,我正试图完全理解它们。根据 perlre:
\Q quote (disable) pattern metacharacters until \E
\E end either case modification or quoted section, think vi
所以我做了几个测试:
$ perl -e 'print "hello\n" if "he\tllo" =~ /\Q\t/'
hello
$ perl -e 'print "hello\n" if "he\tllo" =~ /\t/'
$
如果我理解正确,没有 \Q
它不会评估为 True 因为它将 \t
视为制表符。
然后我用了\E
,我看不出有什么区别:
$ perl -e 'print "hello\n" if "he\tllo" =~ /\Q\t\E/'
hello
如果我给出更广泛的字符串和模式,同时包含文字 \t
和制表符:
$ perl -e 'print "hello\n" if "he\tl\tlo" =~ /\Q\t\E.*\t/'
hello
它似乎有效,因为它将第一个 \t
视为固定字符串,而第二个 \t
被视为制表符。
那么\Q
和\E
是不是应该这样使用呢?也就是说,我们是否将 "clean" 字符串包含在 \Q
和 \E
之间?如果一切都应该被视为文字,只使用 \Q
是否正确?
\E
标记结束,不仅仅是 \Q
,还有其他转义符,例如 \U
。所以当你需要 \Q
序列结束时你会使用它。但我认为你想多了。 \Q
是 quotemeta()
.
的转义版本
"(foobar" =~ /\Q(fo+bar/ # false, "+" gets escaped
"(foobar" =~ /\Q(\Efo+bar/ # true
我不会说"should be used"。如果您不使用 \E
,则 \Q
会继续整个模式。
了解 \E
工作原理的更具体方法是将其与 \U
一起使用:
$ perl -lwe' print "\Ufoobar" '
FOOBAR
$ perl -lwe' print "\Ufoo\Ebar" '
FOObar
如果后面没有危险,则不需要最后的 \E
。我不确定这种行为是否记录在案,但我已经见过很多次了。
看看变量插值如何与 \Q
一起玩也很有趣:
perl -E '$x = "lo$"; say "hello" =~ /$x/'
1
perl -E '$x = "lo$"; say "hello" =~ /\Q$x/'
# ^
# | empty line here.
另见 quotemeta。
就像"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$x\t\E def"
等同于 "abc ".quotemeta($x."\t")." def"
$ diff -u0 \
<( perl -MO=Concise,-exec -E'$_ = "abc \Q$x\t\E 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_text\E/) { ... }
\E
如果在字面量的末尾可以省略。
my $exact_text = "...";
if (/\Q$exact_text/) { ... }
我刚刚阅读了有关 \Q
和 \E
的内容,我正试图完全理解它们。根据 perlre:
\Q quote (disable) pattern metacharacters until \E
\E end either case modification or quoted section, think vi
所以我做了几个测试:
$ perl -e 'print "hello\n" if "he\tllo" =~ /\Q\t/'
hello
$ perl -e 'print "hello\n" if "he\tllo" =~ /\t/'
$
如果我理解正确,没有 \Q
它不会评估为 True 因为它将 \t
视为制表符。
然后我用了\E
,我看不出有什么区别:
$ perl -e 'print "hello\n" if "he\tllo" =~ /\Q\t\E/'
hello
如果我给出更广泛的字符串和模式,同时包含文字 \t
和制表符:
$ perl -e 'print "hello\n" if "he\tl\tlo" =~ /\Q\t\E.*\t/'
hello
它似乎有效,因为它将第一个 \t
视为固定字符串,而第二个 \t
被视为制表符。
那么\Q
和\E
是不是应该这样使用呢?也就是说,我们是否将 "clean" 字符串包含在 \Q
和 \E
之间?如果一切都应该被视为文字,只使用 \Q
是否正确?
\E
标记结束,不仅仅是 \Q
,还有其他转义符,例如 \U
。所以当你需要 \Q
序列结束时你会使用它。但我认为你想多了。 \Q
是 quotemeta()
.
"(foobar" =~ /\Q(fo+bar/ # false, "+" gets escaped
"(foobar" =~ /\Q(\Efo+bar/ # true
我不会说"should be used"。如果您不使用 \E
,则 \Q
会继续整个模式。
了解 \E
工作原理的更具体方法是将其与 \U
一起使用:
$ perl -lwe' print "\Ufoobar" '
FOOBAR
$ perl -lwe' print "\Ufoo\Ebar" '
FOObar
如果后面没有危险,则不需要最后的 \E
。我不确定这种行为是否记录在案,但我已经见过很多次了。
看看变量插值如何与 \Q
一起玩也很有趣:
perl -E '$x = "lo$"; say "hello" =~ /$x/'
1
perl -E '$x = "lo$"; say "hello" =~ /\Q$x/'
# ^
# | empty line here.
另见 quotemeta。
就像"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$x\t\E def"
等同于 "abc ".quotemeta($x."\t")." def"
$ diff -u0 \
<( perl -MO=Concise,-exec -E'$_ = "abc \Q$x\t\E 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_text\E/) { ... }
\E
如果在字面量的末尾可以省略。
my $exact_text = "...";
if (/\Q$exact_text/) { ... }