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

I want to have a function that takes a string and then a find and replace regex ie: where $find could be something like "(\S{20})"
and $replace could be something like "$1 "
sub findandreplace{ my($string,$find,$replace); $string=~s/$find/$replace/g; $string; }
Anyone know how to make this voodoo happen?

Replies are listed 'Best First'.
Re: Having scalars handled as regexs inside a substitution
by chromatic (Archbishop) on May 20, 2000 at 06:01 UTC
    $find is taken care of automatically, but you need to evaluate $replace, twice: $string =~ s/$find/$replace/gee; The first time gives you $1, and the second evaluates that to become the first parenthetical match. Example:
    #!/usr/bin/perl -w use strict; my $string = "abcabcabc"; my $find = "a(bc)"; my $replace = '$1'; $string =~ s/$find/$replace/eeg; print ">>$string<<\n";
    Note that $replace is defined via single quotes. That's to avoid interpolation in the assignment -- otherwise, there's an undefined value error.
Re: Having scalars handled as regexs inside a substitution
by ZZamboni (Curate) on May 20, 2000 at 19:13 UTC
    You could also use eval:
    sub findandreplace { my ($string, $find, $replace)=@_; eval { $string =~ s/$find/$replace/; } die "$@" if $@; $string; }

    --ZZamboni

      Close, but you have to avoid evaluating the first occurance of $string:
      sub findandreplace { my ($string, $find, $replace) = @_; eval '$string' . " =~ s/$find/$replace/"; $string; }

      Otherwise, you end up with the value of $string on the LHS of the =~ instead of the variable $string.
      - Matt
        No. What you say would happen if I had enclosed the eval'ed code in quotes, but because I used braces, it just uses the existing variables, but does not perform a textual substitution.

        Doing substitution with user-supplied patterns in an eval block in quotes is dangerous, because it allows the user to provide things like @{[ code ]} in the patterns, which can execute arbitrary perl code.

        --ZZamboni