Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

Guess I don't have \Q and \E figured out yet...

by Guildenstern (Deacon)
on Apr 30, 2001 at 18:42 UTC ( #76599=perlquestion: print w/replies, xml ) Need Help??

Guildenstern has asked for the wisdom of the Perl Monks concerning the following question:

I ran across a substitution problem the other day that quite baffled me. I'll give a very simple case here as an example. I have a hash whose values are entries to search for and whose values are what to replace with.
my %sub_hash = ( "&somechar;" => "\a111" );

Having been recently apprised of the use of \Q and \E in REs, I knew my substitution statement would have to look something like:
$text =~ s/\Q$foo\E/$sub_hash{$foo}/ig;
The result of this substitution was not the end result that I was looking for, but it was easy to tell what had gone wrong. My replaced text became ox07 (the ASCII bell) followed by the 111. Simple enough to fix, I thought, since it was obvious that the \a portion of the replacement was being converted into the bell character. So I revised my RE to look like this:
$text =~ s/\Q$foo\E/\Q$sub_hash{$foo}\E/ig;
The results of this RE were a bit more confusing. Instead of ending up with \a111 in the replacement text, I got \(ASCII bell)111. The backslash was now showing up, but somehow the ASCII bell character was still being inserted.
Finally, I just changed the values in the hash to look like this:
my %sub_hash = ( "&somechar;" => "\\a111" );

I then reverted back to my original RE, and everything worked as expected.

Why did the \Q and \E in my second RE appear to work incorrectly? I can understand the \a being interpreted as the ASCII bell without the \Q and \E modifiers, but why the a by itself was interpreted as the bell when using the modifiers is beyond me. I hesitate to say that I've found a bug, since it's far more likely that I've simply missed something in my learning of REs.

Negaterd character class uber alles!

Replies are listed 'Best First'.
Re: Guess I don't have \Q and \E figured out yet...
by hdp (Beadle) on Apr 30, 2001 at 18:56 UTC
    This particular problem has little to do with regexes and/or \Q. \a in a doublequoted string will be interpreted as 0x07; the reason your fix works is because you're backslashing the \.

    You didn't actually have "the a by itself" -- by the time your string gets to the regex, \a has already been interpreted as a beep, and so applying \Q leaves you with a backslashed beep. In fact, anything *but* \\a in the original string constant (e.g. using \Q or quotemeta) will be too late to do anything but leave you with a backslashed beep.


      OK, that seems clear hdp, but I'm confused by the following snippet (using \t instead of \a for visibility) in which perlfunc:quotemeta appears to behave differently than /Q/E:
      $foo = "\tfoo"; $_ = ">>ha<<\n"; s/ha/$foo/; print; $_ = ">>ha<<\n"; s/ha/\Q$foo\E/; print; quotemeta $foo; # update: this is doing nothing! $_ = ">>ha<<\n"; s/ha/$foo/; print; $foo = '\tfoo'; $_ = ">>ha<<\n"; s/ha/$foo/; print; $_ = ">>ha<<\n"; s/ha/\Q$foo\E/; print; quotemeta $foo; # update: this is doing nothing! $_ = ">>ha<<\n"; s/ha/$foo/; print;
      which produces:
      >> foo<< >>\ foo<< >> foo<< >>\tfoo<< >>\\tfoo<< >>\tfoo<<
      What am I forgetting here?

      Update Aarghhh! How bloody embarrassing! Thanks tye, that's what I get for minimizing my keystrokes!
      Useless use of quotemeta in void context at D:\Perl\tmp\ line 9.
      Useless use of quotemeta in void context at D:\Perl\tmp\ line 15.
      /me smacks himself in the forehead

      I'd like to be able to assign to an luser

        $foo= '\t\a\b\c'; print "foo=($foo)\n"; quotemeta $foo; print "foo=($foo)\n"; $foo= quotemeta $foo; print "foo=($foo)\n"; __END__ Produces: foo=(\t\a\b\c) foo=(\t\a\b\c) foo=(\\t\\a\\b\\c)

        That is, quotemeta doesn't modify in place, it returns a modified value so your uses of quotemeta are useless.

        If you had turned on warnings, then you would have been told: Useless use of quotemeta in void context at line 5. which is why we often urge people to do stuff like that. q-:

                - tye (but my friends call me "Tye")

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://76599]
Approved by root
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (7)
As of 2020-10-20 09:12 GMT
Find Nodes?
    Voting Booth?
    My favourite web site is:

    Results (209 votes). Check out past polls.