I'd like to do something like this:
my $text = "The owls are not what they seem.";
my $pattern = '(\s+)';
my $replacement = '-$1-';
$text =~ s/$pattern/$replacement/g;
$text should then be: The- -owls- -are- -not- -what- -they- -seem.
But of course it's more like: The-$1-owls-$1-are-$1-not-$1-what-$1-they-$1-seem.
I tried all kinds of backreferences ($1, \1, \g{1}, \g1) and they all didn't work. The /e modifier didn't work either. Is this possible at all?
The purpose is to alter some text inside an object with a line like this: $object->replace('(.)oo', '$1ar')
Any other ideas how this could be done?
Thank you very much.
You could eval and then expand strings using /ee
:
my $text = "The owls are not what they seem.";
my $pattern = '(\s+)';
my $replacement = q{"-$1-"};
$text =~ s/$pattern/$replacement/eeg;
From perldoc perlop:
e
Evaluate the right side as an expression.
ee
Evaluate the right side as a string then eval the result
However, I would feel safer with
my $replacement = sub { "-$1-" };
$text =~ s/$pattern/$replacement->()/eg;
But it all depends on the context in which you are doing this.
Sinan Ünür's solution will work but it still requires the replacement string to be a literal inside the program at some point. If that replacement string comes from data, you'll have to do something a little fancier:
sub dyn_replace {
my ($replace) = @_;
my @groups;
{
no strict 'refs';
$groups[$_] = $$_ for 1 .. $#-; # the size of @- tells us the number of capturing groups
}
$replace =~ s/\$(\d+)/$groups[$1]/g;
return $replace;
}
and then use it like
$text =~ s/$pattern/dyn_replace($replacement)/eg;
Note that this also avoids eval
and allows the use of modifiers like /g. Code taken from this Perl Monks node but I wrote that node so it's ok :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With