in reply to $1 in variable regex replacement string

Maybe I haven't had enough coffee today either, but is this the problem?

#!/usr/bin/perl $foo = "hello"; $f2 = '$foo'; $f3 = "$foo"; print "$f2\n"; print "$f3\n";

Running that causes this to appear:

$foo hello

The single quotes inhibit processing $1 as a variable, it's treated as a string.

Or maybe I just don't know what you want it to do? :-)

-J.

Replies are listed 'Best First'.
Re: Re: $1 in variable regex replacement string
by tachyon (Chancellor) on Feb 12, 2003 at 19:03 UTC

    That is not the problem. The problem is to get the RHS of the regex to interpolate the value captured in $1 into the replacement string and do the substitution.

    On first impressions the logic for wanting to do this appears dubious, especially in the simple case given. It might just make sense if you wanted to use $1, $2, etc simultaneously. I can remember wanting to do this some time back for reasons that now totally elude me. This was followed by the realisation that there are many ways to tacke any given problem and this way has dubious value IMHO. There are two basic solutions I know of - the q("$1blah") method with /ee and the sub{"$1blah"} method - both noted above.

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

      tachyon wrote:
      there are many ways to tackle the problem and this way has dubious value IMHO

      You will have an easy time convincing me of this. As I continue to muddle around with this, my current approach does have the feel of a mis-guided solution strategy. Problem is, this is the only entry door I can see at present and once I get in the room it seems to be full of only less-than-desirable options.

      So let me back off a bit and state the problem in a more general way.

      Given:
        $str (some arbitrary string)
        $pat (a string to be used as a regex pattern)
        $repl (a string to be used as a regex RHS and
              which may contain $1, $2...)

      Can I / How can I perform the indicated regex substitution on $str?

      At this point in this project I *do* have control over the inputs and even the 'API' for the code that calls this routine. But I am hard put to imagine another way of specifying and requesting this kind of functionality.

      But try me... I'm open to suggestions. I would dearly love to find an elegant way of doing this.

        Presumably you want to do something like this example. You would not want stuff passed in $repl like$repl = q/";`arbitrary_command`;$whoops="/ because that will run an arbitrary command unless you are careful. So the answer is you can do it but you probably should not. That said we can sanitise $repl with the substitution shown. Comment it out and uncomment the hack to see the problem.

        my $str = 'abcadefaghi'; my $pat = '(a.)'; my $repl = '$1 '; #$repl = q/";`arbitrary_command`;$whoops="/; $str = munge_string($str, $pat, $repl); sub munge_string { my ( $str, $pat, $repl ) = @_; # make $repl safe to eval $repl =~ s/([^A-Za-z0-9\$])/\\$1/g; $repl = '"' . $repl . '"'; $str =~ s/$pat/$repl/eeg; return $str; } print "$str\n";

        I just don't see the point. If it is your API you are just digging a big hole for yourself I reckon. If you could outline the problem space it would be easier to suggest other methods. It seems you want to abstract the regex from the core code. This seems like it might be a case of one level of abstraction too many.

        cheers

        tachyon

        s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: Re: $1 in variable regex replacement string
by dvergin (Monsignor) on Feb 12, 2003 at 19:26 UTC
    To Joey The Saint -- sadly, I do not think the answer lies in the direction you suggest.

    The problem is that $pat and $repl come as shown to the routine in question from elsewhere. (The code above is, of course, a reduced demo to focus on the problem.) The contents of $1, $2, etc. (if any) are not known until $pat is invoked here, so I do not see an obvious and practical way to *pre*-load the regex vars in $repl using double-quotish behavior. The substitution must be done *after* $repl comes to this routine.

    I did travel a little way down the following path:

    #!/usr/bin/perl -w use strict; my $str = 'abcadefaghi'; my $pat = '(a.)'; my $repl = '\u$1 '; $str =~ s/$pat/ my @save = (undef, $1, $2, $3, $4, $5, $6); $repl =~ s{\$$_}{$save[$_]}g for 1..6; $repl; /eg; print "$str\n";
    ...and that works for the '$1'-type vars without opening up the eval danger. The problem is that this approach then leaves me with having to write more similar code to handle all other special chars (e.g. '\u' as shown) with similar hand-coded replacements. Safe but yucky.