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

Hi all, I have a set of strings stored in an array, and I want to apply a number of regex substitutions to them. The substitutions are arbitrary and liable to change to I want to store the actual regexes in an array at the top of the script like so...

@name_regexes = qw(s/UDP/PLOP/);

I know theres only one substitution in the above array, but the points is I can't get the following to work:

  foreach $string (@strings) {
    
    # Apply each regex
    foreach $regex (@name_regexes) {
      
      $name =~ $regex;
      push(@names, $name);
    }
  }

Nothing happens... the string remains untransformed... btw, the @names array that is pushed is to store the transformed strings. The following works fine but is not generic enough as I want to specify regular expressions as I showed earlier:

$name =~ $regex; #is replaced by the following line
$name =~ s/UDP/PLOP/;

So my hunch is that is the storing of an entire regex in a string that is the problem - i don't think it is being interpretted by Perl properly... does anyone know/had this problem and how I can fix it??

Best wishes, Arun

  • Comment on Storing Regular Expressions as Strings in Array??

Replies are listed 'Best First'.
Re: Storing Regular Expressions as Strings in Array??
by Fletch (Bishop) on May 02, 2002 at 15:55 UTC

    s/foo/bar/ is not just a regular expression, it's a substitution operator. Storing it in a scalar and expecting it to work is going to be just as effective as storing $foo = "2+2" and expecing $bar = $foo to set $bar to 4. You want to

    • read perldoc -f eval
    • consider whether you really want to use eval
    • consider storing coderefs and applying those instead

Re: Storing Regular Expressions as Strings in Array??
by demerphq (Chancellor) on May 02, 2002 at 15:57 UTC
    Hmm. Well qr// only stores the pattern not the replacement.

    You could try setting up a hash or list of closures with the appropriate regex in them:

    my @subs; push @subs,sub{local $_=shift; s/foo/bar/g; $_}; push @subs,sub{local $_=shift; s/baz/zaz/g; $_}; my $string="foo baz"; $_->($string) foreach @subs; print $string;
    Something like that might do the trick...

    Yves / DeMerphq
    ---
    Writing a good benchmark isnt as easy as it might look.

      I had to make the following change to the above snippet to be able to make it work as intended... i.e. the $string ends up as "bar zaz".

      my @subs; push @subs,sub{local $_=shift; s/foo/bar/g; $_}; push @subs,sub{local $_=shift; s/baz/zaz/g; $_}; my $string="foo baz"; $string = $_->($string) foreach @subs; # *** CHANGED *** # print $string;

      Thanks for the code though, it was very helpful

        Doh.

        Of course. The way I did it would work only if the subs were written as

        sub{$_[0]=~s/foo/bar/g; $_[0]}
        Sorry about the confusion...

        Glad it helped out though. :-)

        Yves / DeMerphq
        ---
        Writing a good benchmark isnt as easy as it might look.