in reply to Variable substitute and capturing

I'm sure this is not the best (or even a good) approach, but it works.. hopefully a more decent answer will come up soon...
eval "\$title =~ s/$search/$replace/";

Replies are listed 'Best First'.
Re^2: Variable substitute and capturing
by ikegami (Patriarch) on Jan 16, 2006 at 16:48 UTC

    That won't work, since you didn't escape $search or $replace. Also, you're needlessly recompiling $search if it's already compiled. Use the following instead:

    $escaped_replace = '$1 (\$1.00)'; # Escape \, $, @ and / eval "\$title =~ s/\$search/$escaped_replace/";

    But since the only thing that needs to be compiled is the replace expression (not the entire substitution), the following is even better:

    $quoted_replace = '"$1 (\$1.00)"'; # Escape \, $, @ and /. Add quotes $title =~ s/$search/eval $quoted_replace/e;

    Of course, not using eval EXPR would be even better. In other words, a templating system would be even better. I mentioned this and posted an example in the thread to which I linked in my other post.

    Update: Added "or $replace".

    Update: Oops, davidrw is correct. $search doesn't need escaping.

      It did work .. i'm guessing cause $search is from qr// ..
      use strict; use warnings; my $s = "foobar"; my $search=qr/(foo)(bar)/; my $replace="\$1-\$2"; my $perl = "\$s =~ s/$search/$replace/"; warn $perl; eval $perl; print $s; __OUTPUT__ $s =~ s/(?-xism:(foo)(bar))/$1-$2/ at -e line 1. foo-bar
      I guess escaping $search is better though so that each eval call is dynamic on both ends (search & replace)..

      Also, i had tried the other way, but got an output of "0" instead of "foo-bar":
      perl -le '$s = foobar; $search=qr/(foo)(bar)/; $replace="\$1-\$2"; $s +=~ s/$search/eval $replace/e; print $s'
        You're right. Even without qr//. I've updated my post.
        # qr & no eval $s = qr/\\/; $t = "\\\\"; $t =~ s/$s/!/; print("$t\n"); # qr & eval $s = qr/\\/; $t = "\\\\"; eval "\$t =~ s/$s/!/"; print("$t\n"); # qr & no stringification $s = qr/\\/; $t = "\\\\"; eval "\$t =~ s/\$s/!/"; print("$t\n"); print("\n"); # qq & no eval $s = "\\\\"; $t = "\\\\"; $t =~ s/$s/!/; print("$t\n"); # qq & eval $s = "\\\\"; $t = "\\\\"; eval "\$t =~ s/$s/!/"; print("$t\n"); # qq & no stringification $s = "\\\\"; $t = "\\\\"; eval "\$t =~ s/\$s/!/"; print("$t\n");

        The regexp still gets stringified and recompiled, though.

        This all goes to prove the value of a template system.