You need to distinguish between the search pattern and the replace string. To store the compiled search regex, use
$search = qr/pattern/;
and to use it in a substitution command, just plug it in:
s/$search/replace/g;
To store the entire substitution, I'd go with a subref:
my $rep = sub { $_[0] =~ s/a/b/g };
my $string = "abc";
$rep->($string);
print "$string\n";
| [reply] [d/l] [select] |
$string =~ $regexp works if $regexp contains a regular expression. It doesn't in your case. "s/.../.../" is the Perl substitution operator, not a regular expression.
If given strings, the best way I can think of doing a substitution is:
$regexp = "a";
$subst = "b";
$global = 1;
if ($global) {
$string =~ s/$regexp/$subst/g;
} else {
$string =~ s/$regexp/$subst/;
}
# (?i...) can be used in $regexp for /.../i
# (?m...) can be used in $regexp for /.../m
# (?s...) can be used in $regexp for /.../s
# (?x...) can be used in $regexp for /.../x
# /g cannot be stored in $regexp, thus the need for $global.
# /e cannot be stored in $regexp.
| [reply] [d/l] [select] |
$regexp = qr/a(b+)c/;
$subst = 'c$1a';
my @a = $string =~ $regexp;
$subst =~ s/\$(\d)/$a[$1-1]/ge;
$string =~ s/$regexp/$subst/;
Warning - untested. I know I've used code similar to this in the past with a limited amount of success. (i.e., it worked for me for what I needed it to work for, and this is not a cut&paste job of that code.) | [reply] [d/l] |
Applying eval to a string is a great way to expose yourself to code injection attacks. Maybe you need to tell us more about the "somewhere else" your regex comes from.
What types of regexes are you expecting? | [reply] [d/l] |
There's no injection problem here.
This is just a small utility to convert an Excel spreadsheet into an SQL database. There is a hash to define the mapping, and another to apply any hacks needed to the data:
my %column_match = (
'SP_CITYNAME' => 'pod_city',
'SP_STATE' => 'pod_state',
'SP_POSTALCODE' => 'pod_zip',
'SP_LANDMARKNAME' => 'pod_short_name',
);
my %column_regex = (
'SP_CITYNAME' => 's/\s*$//g',
'SP_LANDMARKNAME' => 's/^Landmark - //',
);
Though I now realize this is hardly flexible enough. What if someone wanted to hack the data with "join(' ',map{ucfirst(lc($_))}split(/\s/,$_[0]));"? | [reply] [d/l] |
my @regexs;
!/^\s*$/ and push @regexs, $_ while <DATA>;
my @smth = ("test_for r1", "+ test_for_r2 +");
$_ = eval for @regexs;
for my $string (@smth){
for(@regexs){
$string =~ /$_/ and print "pattern \"$_\" is ok for \"$string\"$/"
}
}
# STDOUT:
# pattern "(?i-xsm:^\w+\s+\w+$)" is ok for "test_for r1"
# pattern "(?i-xsm:^\W+\w+\W+$)" is ok for "+ test_for_r2 +"
__DATA__
qr{^\w+\s+\w+$}i
qr{^\W+\w+\W+$}i
| [reply] [d/l] |