Deparse nous dit que c'est ce qui est en cours d'exécution:
$find = 'start (.*) end';
$replace = "foo \cA bar";
$var = 'start middle end';
$var =~ s/$find/$replace/;
Cependant,
/$find/foo \1 bar/
Est interprété comme :
$var =~ s/$find/foo $1 bar/;
Malheureusement, il n'existe pas de moyen facile de le faire.
Vous pouvez le faire avec une chaîne eval, mais c'est dangereux.
Le plus sain solution qui fonctionne pour moi est celle-ci:
$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;
Une réfutation à l'encontre de l'ee de la technique:
Comme je l'ai dit dans ma réponse, j'évite de est évaluée comme pour une raison.
$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";
ce code fait exactement ce que vous pensez que cela fonctionne.
Si votre chaîne de substitution est dans une application web, vous venez d'ouvrir la porte à l'exécution de code arbitraire.
Du Bon Travail.
Aussi, il ne sera PAS travailler avec de l'atteinte activé pour cette raison.
$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.
Cependant, le plus prudent technique est sain, sûr, sécuritaire, et n'est pas sans souillure. ( Être assuré tho, la chaîne de caractères qu'elle émet est encore infecté, afin que vous ne perdez pas de sécurité. )