正则表达式包含捕获组,但替换模式未插值以引用匹配变量 $1
中
use strict;
use warnings;
my $regex = '([^ ]+)e s';
my $subst = '$1 ';
my $text = 'fine sand';
print $text =~ s/$regex/$subst/r;
print "\n";
结果是
$1 and
Perl regular expression variables and matched pattern substitution的解决方案建议在替换中使用e
修饰符和eval
;确实如此
print $text =~ s/$regex/eval $subst/er;
会给出所需的
finand
但是,在我的情况下,模式和替换字符串是从第三方用户输入中读取的,因此不能认为它们对于 eval
是安全的。有没有一种方法可以比将其作为代码执行更安全地插入替换字符串?我在这里寻求的只是扩展替换字符串中包含的所有匹配变量。
我目前能想到的最好的一个成语是这样的
$text =~ /$regex/;
sprintf $subst, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, ...
这需要对替换字符串的语法进行轻微更改,但我认为这是可以接受的。然而,可想象的匹配变量的集合是无限的,特别是不支持命名匹配变量。
最佳答案
use String::Substitution qw( sub_copy );
print sub_copy( $text, $regex, $subst );
像 Perl 一样处理替换 '\$1.00'
和 '${1}00'
。
请注意,虽然这可以防止意外/恶意信息泄露和意外/恶意代码执行,但它并不是在任何意义上都是安全的。具体来说,制作一个正则表达式和字符串组合非常容易,其匹配时间比宇宙的生命周期还要长。
关于regex - Perl 包含匹配变量的替换字符串的安全插值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74541634/