Wie führe ich eine Perl-Ersetzung an einer Zeichenfolge durch und behalte dabei das Original bei?

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

  •  09-06-2019
  •  | 
  •  

Frage

Was ist in Perl eine gute Möglichkeit, eine Ersetzung einer Zeichenfolge mithilfe eines regulären Ausdrucks durchzuführen und den Wert in einer anderen Variablen zu speichern, ohne das Original zu ändern?

Normalerweise kopiere ich die Zeichenfolge einfach in eine neue Variable und binde sie dann an die s/// Regex, der die Ersetzung der neuen Zeichenfolge durchführt, aber ich habe mich gefragt, ob es einen besseren Weg gibt, dies zu tun?

$newstring = $oldstring;
$newstring =~ s/foo/bar/g;
War es hilfreich?

Lösung

Dies ist die Redewendung, die ich immer verwendet habe, um eine modifizierte Kopie einer Zeichenfolge zu erhalten, ohne das Original zu ändern:

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

In Perl 5.14.0 oder höher können Sie das neue verwenden /r zerstörungsfreier Substitutionsmodifikator:

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

Notiz:Die oben genannten Lösungen funktionieren auch ohne g zu.Sie funktionieren auch mit allen anderen Modifikatoren.

Andere Tipps

Die Aussage:

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

Was entspricht:

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

Alternativ können Sie ab Perl 5.13.2 verwenden /r So führen Sie eine zerstörungsfreie Substitution durch:

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

Unter use strict, sagen:

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

stattdessen.

Die einzeilige Lösung ist als Schlagwort nützlicher als guter Code;Gute Perl-Programmierer werden es kennen und verstehen, aber es ist viel weniger transparent und lesbar als das zweizeilige Copy-and-Modify-Couplet, mit dem Sie beginnen.

Mit anderen Worten: Ein guter Weg, dies zu tun, ist die Art und Weise, wie Sie sind bereits es tun.Unnötige Prägnanz auf Kosten der Lesbarkeit ist kein Gewinn.

Eine weitere Lösung vor 5.14: http://www.perlmonks.org/?node_id=346719 (siehe Japhys Beitrag)

Wie sein Ansatz nutzt map, es funktioniert auch gut für Arrays, erfordert jedoch Kaskadierung map um ein temporäres Array zu erzeugen (andernfalls würde das Original geändert werden):

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

Ich hasse Foo und Bar.Wer hat sich überhaupt diese nicht beschreibenden Begriffe in der Programmierung ausgedacht?

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

Wenn Sie Perl schreiben mit use strict;, dann werden Sie feststellen, dass die einzeilige Syntax nicht gültig ist, selbst wenn sie deklariert ist.

Mit:

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

Du erhältst:

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

Stattdessen ist die Syntax, die Sie verwendet haben, zwar eine Zeile länger, aber die syntaktisch korrekte Vorgehensweise use strict;.Für mich mit use strict; ist jetzt nur noch eine Gewohnheit.Ich mache es automatisch.Jeder sollte.

#!/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";
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top