I just read about \Q
and \E
and I am trying to fully undertand them. According to perlre:
\Q quote (disable) pattern metacharacters until \E
\E end either case modification or quoted section, think vi
So I did a couple of tests:
$ perl -e 'print "hello\n" if "he\\tllo" =~ /\Q\t/'
hello
$ perl -e 'print "hello\n" if "he\\tllo" =~ /\t/'
$
If I understand it properly, without \Q
it does not evaluate as True because it considers \t
as a tab.
Then I used \E
and I see no difference:
$ perl -e 'print "hello\n" if "he\\tllo" =~ /\Q\t\E/'
hello
If I give a broader string and pattern containing both literal \t
and a tab:
$ perl -e 'print "hello\n" if "he\\tl\tlo" =~ /\Q\t\E.*\t/'
hello
It seems to work, because it considers the first \t
as fixed string, whereas the second \t
is considered a tab.
So is this the way \Q
and \E
should be used? That is, do we enclose the "clean" strings in between \Q
and \E
? Is it correct to just use \Q
if everything should be treated as literal?
\E
marks the end, not just of \Q
, but other escapes, such as \U
. So you would use it when you need the \Q
sequence to end. But I think you are overthinking things. \Q
is the escape version of quotemeta()
.
"(foobar" =~ /\Q(fo+bar/ # false, "+" gets escaped
"(foobar" =~ /\Q(\Efo+bar/ # true
I would not say "should be used". If you do not use \E
, then \Q
continues through your whole pattern.
A more tangible way to see how \E
works is to use it with \U
:
$ perl -lwe' print "\Ufoobar" '
FOOBAR
$ perl -lwe' print "\Ufoo\Ebar" '
FOObar
Just like "abc $x def"
is the same as "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"
is the same as "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
(The difference is just an difference in the indexes in the "pad", the array where lexicals are stored.)
It can also be used in regexp literals.
my $exact_text = "...";
my $pat = quotemeta($exact_text);
if (/$pat/) { ... }
is long for
my $exact_text = "...";
if (/\Q$exact_text\E/) { ... }
\E
can be omitted if it's at the end of the literal.
my $exact_text = "...";
if (/\Q$exact_text/) { ... }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With