Reemplazo de texto con barra inalcadora en una variable en Perl
Pregunta
¿Cómo puedo reemplazar la barra inalcadora dentro de la variable?
$string = 'a\cc\ee';
$re = 'a\\cc';
$rep = "Work";
#doesnt work in variable
$string =~ s/$re/$rep/og;
print $string."\n";
#work with String
$string =~ s/a\\cc/$rep/og;
print $string."\n";
producción:
a\cc\ee
Work\ee
Solución
Porque estás usando esto dentro de una regex, probablemente quieras quotemeta()
o \Q
y \E
(ver perldoc perlre
)
perl -E'say quotemeta( q[a/asf$#@ , d] )'
# prints: a\/asf\$\#\@\ \,\ d
# Or, with `\Q`, and `\E`
$string =~ s/\Q$re\E/$rep/og;
print $string."\n";
Otros consejos
Si te configuras $re = 'a\cc';
, funcionaría. La barra inalcadora no se interpola como espera cuando lo incluye en la regex como una variable: se está utilizando literalmente en la sustitución.
Alternativamente, podría definir la cadena con citas dobles, pero esa no es una buena práctica. Es mejor usar siempre cotizaciones individuales en sus cuerdas a menos que desee interpolar algo explícitamente en el contenido: ahorra una cantidad infitsimal de procesamiento, pero es una pista para el lector en cuanto a lo que pretendía el programador.
El problema es que estás usando citas individuales para definir $re
. Eso significa que cuando lo usa en el patrón de búsqueda, busca dos cortes.
Las citas individuales le dicen a Perl que no interpolaran las cadenas, sino que use los caracteres en bruto. Cada corte se toma literalmente y como un escape.
Comparar:
$re0 = 'a\\cc';
$re1 = "a\\cc";
Cuando los imprima, verá:
print $re0."\n".$re1."\n";
a\\cc
a\cc
Por otro lado, cuando usa la cadena directamente en el Regex, está interpolada, por lo que necesita un corte para actuar como escape, y otro para ser lo que está escapando.