Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re: $1 in variable regex replacement string

by tadman (Prior)
on Feb 12, 2003 at 18:06 UTC ( [id://234772]=note: print w/replies, xml ) Need Help??


in reply to $1 in variable regex replacement string

One workaround is do tweak it slightly, giving you this:
my $repl = '$1 '; $repl =~ s/\"/\\"/g; $repl = qq{"$repl"}; $str =~ s/$path/$repl/eeg;
Note that this involves an eval so you should be very, very careful what you feed it.

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

    For example you would not want it passed:

    $repl = '\";`hacked`;\"';

    You can make this a whole lot safer (maybe even totally safe) with a suitable sanitization of $repl

    sub munge_string { my ( $str, $pat, $repl ) = @_; # make $repl safe to eval $repl =~ tr/\0//d; $repl =~ s/([^A-Za-z0-9\$])/\\$1/g; $repl = '"' . $repl . '"'; $str =~ s/$pat/$repl/eeg; return $str; }

    cheers

    tachyon

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

      Drawing on dvergin's idea, what about this?
      sub safeswitch { my @P = (undef,$1,$2,$3,$4,$5,$6,$7,$8,$9); $_[0] =~ s/\$(\d)/$P[$1]/g; $_[0]; } my $str = "abcdefghijafjafjkagjakg"; my $pat = '(a.)'; my $repl = '$1 '; $str =~ s/$pat/safeswitch($repl)/eg; print $str,$/;
      The advantage here is that you don't end up re-evaluating the function code each time, just the function call.
        This thread has turned into the "Perl Quiz of the Week" #1! ;-)
        Write a subroutine, 'subst', which gets a string argument, $s. It should search $s and replace any occurrences of "$1" with the current value of $1, any occurrences of "$2" with the current value of $2, and so on.

        For example, if $1, $2, and $3 happen to be "dogs", "fish" and "carrots", then

        subst('$2, $1 and $3')
        should return
        "fish, dogs, and carrots"
        dominus' post-mordem analysis of this problem can be found here. He offers several solutions and some discussion of why (and why not) to use them.

        Very nice! So all wrapped up and ready to go you would have:

        my $str = "abcdefghijafjafjkagjakg"; my $pat = '(a.)'; my $repl = '$1 '; print munge($str,$pat,$repl); =head2 munge( STRING, PATTERN, REPLACEMENT ) The munge function takes three arguments and returns a string. The first argument is the STRING to be modified. The modification is performed by s/PATTERN/REPLACEMENT/g. The main advantage of this function is that REPLACEMENT can contain $1, $2 etc that have been captured by PATTERN These values are safely interpolated prior to the substitution being made. =cut sub munge { my($str, $pat, $repl) = @_; $str =~ s/$pat/_safeswitch($repl)/eg; return $str; } # used by munge function to safely interpolate # $1, $2 etc into the replacement string sub _safeswitch { my @P = (undef,$1,$2,$3,$4,$5,$6,$7,$8,$9); $_[0] =~ s/\$(\d)/$P[$1]/g; $_[0]; }

        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 18:35 UTC
    This is the sort of thing I was hoping to avoid.

    Is there any concise way to "be very, very careful" about what would get fed to this snippet. The current source *is* trustable... but I've learned that these things get generalized in future iterations and I want to put in the paranoia now if I go this route.

Re^2: $1 in variable regex replacement string
by RaptorRex (Acolyte) on Aug 17, 2007 at 15:55 UTC
    Applying my 2 cents 4 years too late. I came here tonight looking because I had the same problem as the original poster and after some thinking on the responses I came up with something I didn't see in the other answers (hopefully I read them all, there were alot).

    anyhoo,...

    ApplyRegExRename('witch(\d\d\d)\.jpg','witch_%02d.jpg'); # param 1 = regex expression for find # param 2 = sprintf expression for replacement sub ApplyRegExRename # supports up to 5 caught matches within the patt +ern { my $regex = shift; my $repl = shift; ... my $file2 = $file; $file2 =~ s/$regex/sprintf($repl,$1,$2,$3,$4,$5)/e; print "renaming: $file to $file2\n"; ... }

    Works good enough for my purposes.

    Keep in mind you can be tricky with sprintf expression to reorder how your $1-n vars are consumed as well.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (5)
As of 2024-04-18 07:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found