Hello,
I tried to find a solution that doesn't use eval, although if '$1' is sent
as a parameter to the subroutine as a simple string, I think it either need
to be eval'ed or replaced literally.
I made this solution to work with more capturing parans if necessary:
use strict;
use warnings;
my $data = "foo whatever bar";
$data = substitute_lines( $data, qr/^foo (whatever) bar$/, 'bar $1 baz');
print "$data\n";
$data = "foo whatever bar whatever2 baz";
$data = substitute_lines( $data, qr/^foo (whatever) bar (whatever2) baz$/,
'bar $2 baz $1 foo');
print "$data\n";
sub substitute_lines {
my ($contents, $regex, $subst) = @_;
$contents =~ s/$regex(?{ $contents =~ s[$regex][$subst]gm; my @c =
@{^CAPTURE}; $contents =~ s[\$$_][$c[$_-1]] for 1 .. @c })/$contents/;
return $contents;
}
It prints:
bar whatever baz
bar whatever2 baz whatever foo
However, the regex above uses code interpretation in regex, which is another
kind of eval.
So the following subroutine does the same thing with a simple replacement,
without code interpretation:
sub substitute_lines {
my ($contents, $regex, $subst) = @_;
$contents =~ s/$regex/$subst/gm;
my @matches = @{^CAPTURE};
$contents =~ s/\$$_/$matches[$_-1]/g for 1 .. @matches;
return $contents;
}
----- Original Message -----
From: "Claude Brown via beginners" <beginners@perl.org>
To: "Levi Elias Nystad-Johansen" <levi.johan...@protonmail.com>; "Andrew
Solomon" <and...@geekuni.com>
Cc: "Josef Wolf" <j...@raven.inka.de>; <beginners@perl.org>
Sent: Thursday, October 26, 2023 12:07 AM
Subject: RE: Using qr// with substitution and group-interpolation in the
substitution part
Josef,
Inspired by Levi's “eval” idea, here is my solution:
sub substitute_lines {
my ($contents, $regex, $subst) = @_;
eval "\$contents =~ s/$regex/$subst/g";
return $contents;
}
$data = "foo whatever bar";
$data = &substitute_lines($data, qr/^foo (whatever) bar$/m, 'bar $1 baz');
print "$data\n";
The differences:
- escaped the "$" so the eval gets a literal "$contents"
- didn't escape "$" so the eval receives the value of $regex and $subst
- moved the "g" into the sub as it has no meaning for a qr//
- removed the "m" from the sub as it best left with the original qr//
- added "$data = ..." to get back the value from the subroutine
Cheers,
Claude.
--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/