The regex contains a capture group, but the substitution pattern is not interpolated to reference the match variable $1
in
use strict;
use warnings;
my $regex = '([^ ]+)e s';
my $subst = '$1 ';
my $text = 'fine sand';
print $text =~ s/$regex/$subst/r;
print "\n";
The result is
$1 and
The solution to Perl regular expression variables and matched pattern substitution suggests to use the e
modifier and eval
in the substitution; and indeed
print $text =~ s/$regex/eval $subst/er;
would give the desired
finand
However, in my situation, the pattern and substitution strings are read from third party user input, so they cannot be considered safe for eval
. Is there a way to interpolate the substitution string in a more secure way than to execute it as code? All I seek here is to expand all match variables contained in the substitution string.
The best I can currently think of involves an idiom like
$text =~ /$regex/;
sprintf $subst, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, ...
This would require a slight change in syntax for the substitution string, but I consider this acceptable. However, the set of imaginable match variables is infinite, in particular named match variables would not be supported.