On Wed, Dec 26, 2012 at 10:29 AM, Paul Johnson <p...@pjcj.net> wrote:
> On Wed, Dec 26, 2012 at 04:10:06PM +0100, gator...@yahoo.de wrote:
>> Hi,
>>
>> I would like to store regular expressions and substitution strings in
>> a hash variable. If a given string matches any of the stored patterns,
>> the corresponding substitution should be applied. What originally looked
>> trivial turned out to be quite a challenge, particularly if the
>> substitution string contains references to capture buffers.
>>
>> Here's a minimal example:
>>
>> my $rx=qr/^aaaa_(.*)/;
>> my $r='a_$1';
>> my $s="aaaa_bla_fasel_blub";
>> if ($s=~ /$rx/) { # pattern matches, apply substitution if you can
>>     # hardcoded, it's trivial:
>>     # $s =~ s/$rx/a_$1/;
>>     # but how to interpolate the capture buffer? Not like this:
>>     # eval '$s="$r"';
>>     # eval { $s=$r };
>>     # $s =~ s/$rx/$r/e;
>> }
>>
>> Can anybody think of a straightforward way to do this?
>
> This is a situation where string eval is warranted:
>
> eval "\$s =~ s/\$rx/$r/";

I'd recommend against the use of string eval  if at
all possible. There's the trusted input issue which
you cite but also additional complications if the
input does need to be inspected/laundered:
  See  perldoc -q taint

Also, you can usually arrange to avoid eval or
 s///ee totally with a  differently crafted regex.
See Timothy's post.  A "no eval" solution will be
faster too and you won't need to examine $@.

> ...
>  - there's no need to check if the pattern matches first, just attempt
>    the substitution

It may be a good sanity check to do so though if you're always
expecting the substitution to succeed. Otherwise,
even though the eval works,  a failed pattern match will
fail silently. But you could still report failure by checking
the substitution return:

    s/.../....../ or carp "pattern failed";

-- 
Charles DeRykus

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to