Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to save a substitution regex (search/replace) in a variable, similar to qr//

Tags:

regex

perl

I'm trying to store a s/ / /g regex as a variable (without much luck).

Here is an example that uses a normal match to show what I intend to do.

my %file_structure = (
    header => qr/just another/,
    table  => qr/perl beginner/,
)

Now I can call this using $line =~ $file_structure{'header'} and it will return undef, or true if the pattern matches.

However I would like to say $line =~ $file_structure{'foo'} where $file_structure{'foo'} contains something like s/beginner/hacker/g.

like image 649
Chris R Avatar asked Feb 05 '11 03:02

Chris R


2 Answers

You should store the 2 parts separately:

my %file_structure = (
    foo => {pat => qr/beginner/, repl => 'hacker'},
);

my $line = 'just another perl beginner';
$line =~ s/$file_structure{foo}{pat}/$file_structure{foo}{repl}/;
print "$line\n";

Which would be much safer than resorting to an evil "eval EXPR":

my %file_structure = (
    foo => 's/beginner/hacker/',
);

my $line = 'just another perl beginner';
eval "\$line =~ $file_structure{foo}";
print "$line\n";
like image 193
tadmc Avatar answered Oct 05 '22 19:10

tadmc


As you have found, there is no way to directly store a substitution regex like you can a match regex (with qr//). You can break the parts up and recombine them as tadmc shows. Another way to do this is to store the substitution in a subroutine:

my %file_structure = (
   foo_uses_default => sub {s/foo/bar/},
   foo_takes_arg    => sub {$_[0] =~ s/foo/bar/},
   foo_does_either  => sub {(@_ ? $_[0] : $_) =~ s/foo/bar/},
);

$file_structure{foo_uses_default}() for ...;
$file_structure{foo_uses_arg}($_)   for ...;
like image 45
Eric Strom Avatar answered Oct 05 '22 18:10

Eric Strom