Депарс говорит нам, что это то, что выполняется:
$find = 'start (.*) end';
$replace = "foo \cA bar";
$var = 'start middle end';
$var =~ s/$find/$replace/;
Однако
/$find/foo \1 bar/
интерпретируется как:
$var =~ s/$find/foo $1 bar/;
К сожалению, похоже, что сделать это нелегко.
Вы можете сделать это с помощью строки eval, но это опасно.
Самым здравым решением, которое мне подходит, было следующее:
$find = "start (.*) end";
$replace = 'foo \1 bar';
$var = "start middle end";
sub repl {
my $find = shift;
my $replace = shift;
my $var = shift;
# Capture first
my @items = ( $var =~ $find );
$var =~ s/$find/$replace/;
for( reverse 0 .. $#items ){
my $n = $_ + 1;
# Many More Rules can go here, ie: \g matchers and \{ }
$var =~ s/\\$n/${items[$_]}/g ;
$var =~ s/\$$n/${items[$_]}/g ;
}
return $var;
}
print repl $find, $replace, $var;
Опровержение против техники ee:
Как я сказал в своем ответе, я избегаю зла по какой-то причине.
$find="start (.*) end";
$replace='do{ print "I am a dirty little hacker" while 1; "foo $1 bar" }';
$var = "start middle end";
$var =~ s/$find/$replace/ee;
print "var: $var\n";
этот код делает именно то, что вы думаете.
Если ваша строка подстановки находится в веб-приложении, вы просто открыли дверь для выполнения произвольного кода.
Хорошая работа.
Кроме того, он НЕ БУДЕТ работать с включенными портами по этой самой причине.
$find="start (.*) end";
$replace='"' . $ARGV[0] . '"';
$var = "start middle end";
$var =~ s/$find/$replace/ee;
print "var: $var\n"
$ perl /tmp/re.pl 'foo $1 bar'
var: foo middle bar
$ perl -T /tmp/re.pl 'foo $1 bar'
Insecure dependency in eval while running with -T switch at /tmp/re.pl line 10.
Тем не менее, более осторожная техника - вменяемая, безопасная, надежная, и не ошибаются. (Будьте уверены, что испускаемая строка все еще испорчена, поэтому вы не потеряете безопасность.)