Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > \Q acts differently in s/// and m// operations

Reply
Thread Tools

\Q acts differently in s/// and m// operations

 
 
gargoyle
Guest
Posts: n/a
 
      02-17-2005
Consider the following code:

#!/usr/bin/perl -w
# NOTE: don't focus on the backslashes, I already know Win32 can
# use / instead. This is simply a regex+metachar question...

$old = 'C:\\test\\1\\'; # old parent dir
$new = 'C:\\test\\2\\'; # new parent dir
$path = 'C:\\test\\1\\bin\\'; # the path we're renaming
warn "old=$old, new=$new, path=$path\n";

warn "----- doing match! -----\n";
$path =~ /^(\Q$old\E)/; # this matches
warn "captured \$1 = $1\n";
$path =~ /^(\Q$new\E)/; # this doesn't
warn "captured \$1 = $1\n";
warn "old=$old, new=$new, path=$path\n";

warn "----- doing substitution! -----\n";
$path =~ s/^\Q$old\E/\Q$new\E/;
warn "old=$old, new=$new, path=$path\n";
__END__

The output:

old=C:\test\1\, new=C:\test\2\, path=C:\test\1\bin\
----- doing match! -----
captured $1 = C:\test\1\
captured $1 = C:\test\1\
old=C:\test\1\, new=C:\test\2\, path=C:\test\1\bin\
----- doing substitution! -----
old=C:\test\1\, new=C:\test\2\, path=C\:\\test\\2\\bin\

In the m// operation, the captured output is the original variable, not
the quotemeta version.

But in the s/// operation, the output is quoted.

Why are they behaving differently? And is there a way to get unquoted
output from the s/// operation, or am I just better off using substr(),
since after all there's no unquotemeta() function?

 
Reply With Quote
 
 
 
 
Bob Walton
Guest
Posts: n/a
 
      02-17-2005
gargoyle wrote:

....
> In the m// operation, the captured output is the original variable, not
> the quotemeta version.
>
> But in the s/// operation, the output is quoted.
>
> Why are they behaving differently? And is there a way to get unquoted
> output from the s/// operation, or am I just better off using substr(),
> since after all there's no unquotemeta() function?
>


Well, the "replacement" in the s/// operator is a *string*, not a
regexp. And that string is processed per qq(). For that, \Q has
a different meaning -- all non-word characters following \Q are
quoted, just as you noted above. In the m// regexp, it is the
*regexp* characters that are quoted, and not any characters in
the matched string. You probably should simply dispense with the
\Q and \E in your replacement string. For details, see:

perldoc perlop

particularly the sections on quote and quote-like operators and
on regexp quote-like operators.

And there *is* an "unquotemeta" function for a string quoted by
\Q -- eval(qq(qq/$string/)) should do the trick, I think, as in:

d:\junk>perl -e "$a=qq(ab\Q~!@#\E~!@#);print eval qq/qq($a)/"
ab~!@#~!@#
d:\junk>

--
Bob Walton
Email: http://bwalton.com/cgi-bin/emailbob.pl
 
Reply With Quote
 
 
 
 
gargoyle
Guest
Posts: n/a
 
      02-17-2005
On 2005-02-17, Bob Walton <(E-Mail Removed)> wrote:
> Well, the "replacement" in the s/// operator is a *string*, not a
> regexp. And that string is processed per qq(). For that, \Q has
> a different meaning -- all non-word characters following \Q are
> quoted, just as you noted above.


Aha! Now I understand. Thanks for clearing that up.

> And there *is* an "unquotemeta" function for a string quoted by
> \Q -- eval(qq(qq/$string/)) should do the trick, I think, as in:
>
> d:\junk>perl -e "$a=qq(ab\Q~!@#\E~!@#);print eval qq/qq($a)/"
> ab~!@#~!@#
> d:\junk>


Interesting... But I have trouble understanding the impact of several
levels of quoting and interpolation. It's late though, so I'll re-read
the perlop manpage tomorrow and see if I can make sense of it.
 
Reply With Quote
 
Ilya Zakharevich
Guest
Posts: n/a
 
      02-17-2005
[A complimentary Cc of this posting was sent to
Bob Walton
<(E-Mail Removed)>], who wrote in article <crTQd.15377$(E-Mail Removed)>:
> Well, the "replacement" in the s/// operator is a *string*, not a
> regexp. And that string is processed per qq().


Correct.

> For that, \Q has
> a different meaning


Wrong. \Q has the same meaning everywhere.

> -- all non-word characters following \Q are quoted


That's it.

> In the m// regexp, it is the *regexp* characters that are quoted,
> and not any characters in the matched string.


Wrong. But since quoting some characters is a NOOP (e.g., \: matches
the same as : ), the semantic is somewhat similar to what you wrote -
which is probably the reason for your confusion.

> You probably should simply dispense with the \Q and \E in your
> replacement string.


Without reading the mind of the author, giving any advice does not
make sense. I would just note that

s(REX)(\Q$var);

is the same as

$repl = quotemeta $var;
s(REX)($repl);

(but the first version is much harder to debug).

Hope this helps,
Ilya
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
UpdatePanel acts differently inside Content area of Master Page John Kotuby ASP .Net 3 02-15-2008 01:10 AM
subprocess call acts differently than command line call? Jim Python 2 06-07-2007 07:58 PM
stand-alone JMS, other JDBC operations, and transactions ( ActiveMQ + JOTM + JDBC operations ) Jesus M. Salvo Jr. Java 2 02-11-2006 06:33 PM
== operator acts differently in perl 5.005_03 and 5.8.2 Yahav Perl Misc 10 03-23-2005 03:07 PM
Web Form acts differently when using C# than VB Joe Fallon ASP .Net 1 02-15-2004 10:53 PM



Advertisments