fedorqui
fedorqui

Reputation: 289565

What is \Q in Perl? Is it always necessary to use \E?

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

Answers (3)

ikegami
ikegami

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

choroba
choroba

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

TLP
TLP

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

Related Questions