¿Cómo realizo una sustitución de Perl en una cadena manteniendo el original?

StackOverflow https://stackoverflow.com/questions/22836

  •  09-06-2019
  •  | 
  •  

Pregunta

En Perl, ¿cuál es una buena manera de realizar un reemplazo en una cadena usando una expresión regular y almacenar el valor en una variable diferente, sin cambiar el original?

Por lo general, simplemente copio la cadena a una nueva variable y luego la vinculo al s/// expresión regular que reemplaza la nueva cadena, pero me preguntaba si hay una mejor manera de hacer esto.

$newstring = $oldstring;
$newstring =~ s/foo/bar/g;
¿Fue útil?

Solución

Este es el modismo que siempre he usado para obtener una copia modificada de una cadena sin cambiar el original:

(my $newstring = $oldstring) =~ s/foo/bar/g;

En perl 5.14.0 o posterior, puede utilizar el nuevo /r modificador de sustitución no destructivo:

my $newstring = $oldstring =~ s/foo/bar/gr; 

Nota:Las soluciones anteriores funcionan sin g también.También funcionan con cualquier otro modificador.

Otros consejos

La declaración:

(my $newstring = $oldstring) =~ s/foo/bar/g;

Lo que equivale a:

my $newstring = $oldstring;
$newstring =~ s/foo/bar/g;

Alternativamente, a partir de Perl 5.13.2 puedes usar /r para hacer una sustitución no destructiva:

use 5.013;
#...
my $newstring = $oldstring =~ s/foo/bar/gr;

Bajo use strict, decir:

(my $new = $original) =~ s/foo/bar/;

en cambio.

La solución de una sola línea es más útil como lema que como buen código;Los buenos programadores de Perl lo sabrán y lo entenderán, pero es mucho menos transparente y legible que el pareado de dos líneas de copiar y modificar con el que estás empezando.

En otras palabras, una buena manera de hacerlo es la forma en que estás ya haciéndolo.La concisión innecesaria a costa de la legibilidad no es una victoria.

Otra solución anterior a 5.14: http://www.perlmonks.org/?node_id=346719 (ver la publicación de japhy)

Como su enfoque utiliza map, también funciona bien para matrices, pero requiere conexión en cascada map para producir una matriz temporal (de lo contrario, se modificaría el original):

my @orig = ('this', 'this sucks', 'what is this?');
my @list = map { s/this/that/; $_ } map { $_ } @orig;
# @orig unmodified

Odio foo y bar..¿Quién inventó estos términos no descriptivos en programación?

my $oldstring = "replace donotreplace replace donotreplace replace donotreplace";

my $newstring = $oldstring;
$newstring =~ s/replace/newword/g; # inplace replacement

print $newstring;
%: newword donotreplace newword donotreplace newword donotreplace

Si escribes Perl con use strict;, entonces encontrará que la sintaxis de una línea no es válida, incluso cuando se declara.

Con:

my ($newstring = $oldstring) =~ s/foo/bar/;

Usted obtiene:

Can't declare scalar assignment in "my" at script.pl line 7, near ") =~"
Execution of script.pl aborted due to compilation errors.

En cambio, la sintaxis que ha estado usando, aunque es una línea más larga, es la forma sintácticamente correcta de hacerlo con use strict;.Para mí, usando use strict; Es sólo un hábito ahora.Lo hago automáticamente.Todos deberían.

#!/usr/bin/env perl -wT

use strict;

my $oldstring = "foo one foo two foo three";
my $newstring = $oldstring;
$newstring =~ s/foo/bar/g;

print "$oldstring","\n";
print "$newstring","\n";
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top