Enclose the substitute in single quotes and substitute with the /e switch on.
It would be good practice to compile the regex with qr// before passing it as an argument. That way the caller can apply its own needs about escaping regex special characters.
| [reply] |
Am I doing something wrong? I need two e's, with a modified replacement pattern. Running with two e's on the original replacement gives a compile error.
use strict;
use warnings;
my $test_data = 'This is some test data: $888...!';
my $pattern = qr{(\$?[0-9,]+)};
my $replacement = '<test>$1<\/test>';
my $first_test = apply_regex_e($test_data, $pattern, $replacement);
$replacement = 'q{<test>}.$1.q{<\/test>}';
my $second_test = apply_regex_ee($test_data, $pattern, $replacement);
print $first_test, "\n", $second_test;
sub apply_regex_e {
my ($data, $pat, $rep) = @_;
$data =~ s/$pat/$rep/e;
return $data;
}
sub apply_regex_ee {
my ($data, $pat, $rep) = @_;
$data =~ s/$pat/$rep/ee;
return $data;
}
Output
This is some test data: <test>$1<\/test>...!
This is some test data: <test>$888<\/test>...!
| [reply] [d/l] [select] |
Nope, you're doing it right, I missed a layer of eval. Since the substitute is a string variable containing another variable to interpolate, two evals are needed.
| [reply] |
I'm sorry, but I don't really recommend Zaxo's double e solution for serious purposes, as two e modifiers will have to evaluate the code on the right side every time a match is found and the replacement has to be calculated. A double e switch should usually be avoioded, just like a string eval.
(If this isn't clear, s/$pat/$rep/ee is about the same as s/$pat/eval($rep)/e, and here the eval has to be run every time the pattern matches the string.)
A better solution would be to pass the replacement as a subroutine, so that the code doesn't have to be compiled multiple times. The first e modifier doesn't have to do this, as the code that generates the replacement string is always the same, so it doesn't have to be recompiled every time a match is found.
(Of course, if the replace text is a constant string, you wouldn't need any e's.)
(This is of course for the case of your apply_regex_ee, where the replacement has to be computed. If the replacement is a constant string, as in apply_regex_e, you don't even need a single e, although it doesn't make the solution any worse to have the e switch there.)
Here's my version of the code. I'd like to thank chester for the clean example code.
use strict;
use warnings;
my $test_data = 'This is some test data: $888...!';
my $pattern = qr{(\$?[0-9,]+)};
my $replacement = '<test>$1<\/test>';
my $first_test = replace_with_constant($test_data, $pattern, $replacem
+ent);
my $replacement_func = sub { "<test>" . $1 . "<\/test>"; };
# OR my $replacement_func = sub { "<test>$1<\/test>"; };
my $second_test = replace_with_dynamic($test_data, $pattern, $replacem
+ent_func);
print $first_test, "\n", $second_test, "\n";
sub replace_with_constant {
my ($data, $pat, $rep) = @_;
$data =~ s/$pat/$rep/;
# OR $data =~ s/$pat/$rep/e;
return $data;
}
sub replace_with_dynamic {
my ($data, $pat, $rep) = @_;
$data =~ s/$pat/&$rep()/e;
return $data;
}
Update 2009 april 1: this seems to be a common question, Regular expression "replace string interpolation" problem asks it again.
| [reply] [d/l] [select] |
Thank you Very much. I was unaware of the /e modifier.
| [reply] |