Regex Perl元编程:何时对s//的替换值使用quotemeta是不安全的?

Regex Perl元编程:何时对s//的替换值使用quotemeta是不安全的?,regex,perl,metaprogramming,Regex,Perl,Metaprogramming,Perl运算符通常在s///的搜索端工作,但是在生成要编译的代码时,我应该如何保护应该按字面意思使用但可能包含诸如$1之类位的替换项 使用表格的代码 my $replace = quotemeta $literal_replacement; my $code = eval <<EOCode; sub { s/.../$replace/ } EOCode my$replace=quotemeta$literal\u replacement; 我的$code=eval据我所知,只

Perl运算符通常在
s///
的搜索端工作,但是在生成要编译的代码时,我应该如何保护应该按字面意思使用但可能包含诸如
$1
之类位的替换项

使用表格的代码

my $replace = quotemeta $literal_replacement;

my $code = eval <<EOCode;
  sub { s/.../$replace/ }
EOCode
my$replace=quotemeta$literal\u replacement;

我的$code=eval据我所知,只要不在替换项上添加/e标志,perl就不会用$replace做神奇的事情。所以quotemeta总是会改变你的结果,因为它会包含很多反斜杠

#!/usr/bin/perl

$test="test";

$literal_replacement='Hello $1, or \1';
my $replace = quotemeta $literal_replacement;
$test =~ s/test/$replace/;

print $test,"\n";
返回:

Hello\ \$1\,\ or\ \\1

这可能不是您想要的:

替换端是一个普通的插值字符串(除非您开始添加
/e
修饰符,在这种情况下,它会变成与
/e
修饰符一样多的字符串
eval
s)。Perl 5不关心插入字符串的变量中的内容。这与:

my $foo = 5;
my $bar = '$foo';
my $baz = "$foo $bar"; 
print "$baz\n"; #this is 5 $foo not 5 5

替换通常像双引号字符串一样处理,但您可以使用单引号作为分隔符来更改:

$test =~ s<test>'$replace';
$test=~s'$replace';

谢谢您的回答。我问得不好,遗漏了重要的背景。请查看更新的问题。谢谢您的回答。我问得不好,遗漏了重要的背景。请查看更新的问题。谢谢您的回答。我问得不好,遗漏了重要的背景。请看更新的问题。我想我在这方面帮不了你。我甚至无法想象你为什么要这么做。你到底为什么要这么做?@Chas这很像perlfunc的文章中的例子中使用的技术。你确定这不是过早优化吗?这会给你自己带来很多问题,我怀疑这不会对你的运行时间产生重大影响。你为什么还要使用string eval呢?只需执行我的$code=sub{s/../$literal\u replacement/};这不会插入$literal_replacement的内容,只是将其用作一个literal replacement字符串。@MkV-我理解他的问题,他希望$1在字符串中工作,但没有其他内容。-我不知道如果不显式地编码该行为,如何保证这一点。