I should add that if the script reads values of $regex or $subst from an 
external source, then my use of eval is seriously flawed.  For example, that 
external source might provide this value for $subst:

        /; system("do-bad-things"); qr/x/

The eval will execute the "do-bad-things" command on your system.  


-----Original Message-----
From: Claude Brown via beginners <beginners@perl.org> 
Sent: Thursday, October 26, 2023 8:07 AM
To: Levi Elias Nystad-Johansen <levi.johan...@protonmail.com>; Andrew Solomon 
<and...@geekuni.com>
Cc: Josef Wolf <j...@raven.inka.de>; beginners@perl.org
Subject: RE: Using qr// with substitution and group-interpolation in the 
substitution part

CAUTION: This email originated from outside of the organization. Do not click 
links or open attachments unless you recognize the sender and know the content 
is safe.

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.

Reply via email to