Reputation: 289565
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?
Upvotes: 4
Views: 5055
Reputation: 385655
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/) { ... }
Upvotes: 3
Reputation: 241828
The final \E
is not needed if nothing dangerous follows it. I'm not sure this behaviour is documented, but I've seen it many times.
It's also interesting to see how variable interpolation plays with \Q
:
perl -E '$x = "lo\$"; say "hello" =~ /$x/'
1
perl -E '$x = "lo\$"; say "hello" =~ /\Q$x/'
# ^
# | empty line here.
See also quotemeta.
Upvotes: 1
Reputation: 67900
\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
Upvotes: 5