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