Comment effectuer une substitution Perl sur une chaîne tout en conservant l’original?

En Perl, comment effectuer un remplacement sur une chaîne en utilisant une expression régulière et stocker la valeur dans une variable différente, sans changer l’original?

Je copie généralement la chaîne dans une nouvelle variable, puis la lie à la regex s/// qui fait le remplacement sur la nouvelle chaîne, mais je me demandais s’il y avait un meilleur moyen de le faire.

 $newssortingng = $oldssortingng; $newssortingng =~ s/foo/bar/g; 

C’est le langage que j’ai toujours utilisé pour obtenir une copie modifiée d’une chaîne sans changer l’original:

 (my $newssortingng = $oldssortingng) =~ s/foo/bar/g; 

Dans perl 5.14.0 ou version ultérieure, vous pouvez utiliser le modificateur de substitution non destructif new /r :

 my $newssortingng = $oldssortingng =~ s/foo/bar/gr; 

Note: Les solutions ci-dessus fonctionnent sans g . Ils travaillent également avec d’autres modificateurs.

La déclaration:

 (my $newssortingng = $oldssortingng) =~ s/foo/bar/g; 

Ce qui équivaut à:

 my $newssortingng = $oldssortingng; $newssortingng =~ s/foo/bar/g; 

Sinon, à partir de Perl 5.13.2, vous pouvez utiliser /r pour effectuer une substitution non destructive:

 use 5.013; #... my $newssortingng = $oldssortingng =~ s/foo/bar/gr; 

Sous use ssortingct , dites:

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

au lieu.

La solution à une ligne est plus utile que le code; les bons codeurs Perl le sauront et le comprendront, mais il est beaucoup moins transparent et lisible que le couplet de copier-modifier à deux lignes par lequel vous commencez.

En d’autres termes, une bonne façon de faire est la façon dont vous le faites déjà . La concision inutile au désortingment de la lisibilité n’est pas une victoire.

Je déteste foo et bar .. qui a imaginé ces termes non descriptifs dans la programmation de toute façon?

 my $oldssortingng = "replace donotreplace replace donotreplace replace donotreplace"; my $newssortingng = $oldssortingng; $newssortingng =~ s/replace/newword/g; # inplace replacement print $newssortingng; %: newword donotreplace newword donotreplace newword donotreplace 

Une autre solution pré-5.14: http://www.perlmonks.org/?node_id=346719 (voir l’article de japhy)

Comme son approche utilise la map , elle fonctionne également bien pour les tableaux, mais nécessite une map cascade pour produire un tableau temporaire (sinon l’original serait modifié):

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

Si vous écrivez Perl avec use ssortingct; , alors vous constaterez que la syntaxe d’une ligne n’est pas valide, même lorsqu’elle est déclarée.

Avec:

 my ($newssortingng = $oldssortingng) =~ s/foo/bar/; 

Vous obtenez:

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

Au lieu de cela, la syntaxe que vous avez utilisée, une ligne plus longue, est la manière syntaxiquement correcte de le faire avec use ssortingct; . Pour moi, utiliser use ssortingct; est juste une habitude maintenant. Je le fais automatiquement. Tout le monde devrait.

 #!/usr/bin/env perl -wT use ssortingct; my $oldssortingng = "foo one foo two foo three"; my $newssortingng = $oldssortingng; $newssortingng =~ s/foo/bar/g; print "$oldssortingng","\n"; print "$newssortingng","\n";