Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

substitution interpolation?

by h0mee (Acolyte)
on May 31, 2001 at 04:44 UTC ( [id://84420]=perlquestion: print w/replies, xml ) Need Help??

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

I'm trying to write an interface for my team which will allow them to enter arbitrary regular expressions for purposes of search and replace. I'm having some trouble getting backreferences to work correctly in the right hand side of s///. I've tried the following bits of code:
my $var = "my dog spot"; my $expr = qr|(my dog) spot|; my $sub = qr|\1 spooge|; $var =~ s/$expr/$sub/; print $var #error: "/\1 spooge/: reference to nonexistent group"
Rats. So then I tried:
my $var = "my dog spot"; my $expr = qr|(my dog) spot|; my $sub = qr|$1 spooge|; $var =~ s/$expr/$sub/; print $var; #prints: (?-xism: spooge)
Trying to be clever doesn't work either:
my $var = "my dog spot"; my $expr = qr|(my dog) spot|; my $sub = qq|$1 spooge|; $var =~ s/$expr/qr|$sub|/e; print $var; #prints (?-xism: spooge)

And of course, the obvious method:
my $var = "my dog spot"; my $expr = qq|(my dog) spot|; my $sub = qq|\1 spooge|; #could be $1 $var =~ s/$expr/$sub/e; #prints " spooge"
How do I get it so that it prints: "my dog spooge"? Given the above example where I don't know what my matching pattern or subsitution pattern is going to be? Again, it works fine if I don't have backrefs- but backreferences are pretty critical to the work we are doing. Thanks!!! h0mee

Replies are listed 'Best First'.
Re: substitution interpolation?
by h0mee (Acolyte) on May 31, 2001 at 05:20 UTC

      First off it's wrong to use qr// on rhs of s///

      You must realize that the left side of s/// is the regular expression, and that the right side is merely the the substitute string ( or that which produces the substitute string)

      So in effect what you are doing is:

      $var =~ s/ < regex $expr > / < scalar representation of $sub > /

      This is why you end up with the string (?-xism: spooge), which is the scalar value of $sub


      In the node you referred to, they eval'ed the rhs one way or the other. mdillon eval'ed the rhs only ( $1 . "ar" ) by using /ee ( read perlop ), and knight eval'ed the entire perl expression ( "s/$lhs/$rhs/" ).

        Thanks for pointing out my totally clueless use of qr// (was going on the advice of someone on IRC when I went down that path, instead of RTFM'ing). What I don't understand is- why does the evaling the entire expression work? Does it force interpolation of $lhs and $rhs before the expression is evaluated? In experiments,
        $_ = $var; eval "s/$lhs/$rhs/";
        works, but:
        eval "$var =~ /$lhs/$rhs/;";
        doesn't work- what am I missing?
Re: substitution interpolation?
by tachyon (Chancellor) on May 31, 2001 at 07:14 UTC

    Do it this way

    tachyon

    my $var = "my dog spot"; my $expr = "(my dog) spot"; $var =~ m/$expr/; my $sub = "$1 spooge"; $var =~ s/$expr/$sub/; print $var;

    By matching first we define $1. When we define $sub $1 is interpolated into the string. We then do the substitution with the replacement string fully formed, and ta da - it works

    Cheers

      If I may make a minor comment, I don't think it is a good idea to call a scalar $sub. When I was reading the code my eye missed the '$' and I thought that you were doing something unusual to a subroutine.

      If you just called the scalar $subst the initial confusion would go away.

Re: substitution interpolation?
by grinder (Bishop) on May 31, 2001 at 12:03 UTC

    I don't know if you have the liberty of reformulating the contents of $sub, but if instead of '$1 spooge' maybe you can use '$1.q{ spooge}' and from there you can employ the /ee switch and gain major Perl purity points!

    my $var = "my dog spot"; my $expr = "(my (dog|cat)) spot"; my $sub = '$1.q{ spooge}'; $var =~ s/$expr/$sub/ee; print $var;

    --
    g r i n d e r
      bugger, I was just going to post this:
      #!perl -w use strict; my $var = "my dog spot"; my $expr = q|(my dog) spot|; my $sub = q|$1.' spooge'|; $var =~ s/$expr/$sub/ee; print $var;

      "Argument is futile - you will be ignorralated!"

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (5)
As of 2024-04-19 09:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found