212 Stimmen

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

Wie kann man in Perl eine Zeichenkette mit einem regulären Ausdruck ersetzen und den Wert in einer anderen Variablen speichern, ohne das Original zu verändern?

Normalerweise kopiere ich die Zeichenkette einfach in eine neue Variable und binde sie dann an die s/// regex, die die Ersetzung auf die neue Zeichenfolge, aber ich frage mich, ob es einen besseren Weg, um dies zu tun?

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

300voto

John Siracusa Punkte 14511

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

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

In Perl 5.14.0 oder später können Sie die neue /r nicht-destruktiver Substitutionsmodifikator :

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

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

ALSO SEHEN:
perldoc perlrequick : Schnellstart für reguläre Ausdrücke in Perl

6 Stimmen

Ob unter strengem Gebrauch oder nicht. Minimales Scoping von Variablen++

0 Stimmen

Ich habe mich gefragt, ob etwas wie my $new = $_ for $old =~ s/foo/bar; funktionieren würde?

2 Stimmen

@Benoit, ich glaube, Sie meinen s/foo/bar/ for my $newstring = $oldstring; Es funktioniert, aber es ist noch viel seltsamer.

51voto

Pat Punkte 35602

Die Erklärung:

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

Das ist gleichbedeutend mit:

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

Alternativ können Sie ab Perl 5.13.2 auch /r um eine nicht destruktive Substitution durchzuführen:

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

3 Stimmen

Haben Sie die g in Ihrer Top-Regex?

26voto

Sam Kington Punkte 1202

Unter use strict , sagen:

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

stattdessen.

14voto

Josh Millard Punkte 1075

Die Einzeiler-Lösung ist eher ein Schibboleth als guter Code; gute Perl-Programmierer werden sie kennen und verstehen, aber sie 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 der Weg, den Sie bereits es zu tun. Unnötige Prägnanz auf Kosten der Lesbarkeit ist kein Gewinn.

0 Stimmen

Ah, aber die einzeilige Version unterliegt nicht dem in der Frage erwähnten Fehler, versehentlich die falsche Zeichenfolge zu ändern.

1 Stimmen

Die einzeilige Version, <i>wenn sie korrekt ausgeführt wird</i>, ist nicht subjektiv, wahr. Aber das ist ein anderes Thema.

13 Stimmen

Man könnte meinen, das sei unnötig knapp, aber wenn man einen Variablennamen zweimal eingeben muss, um ihn einmal zu verwenden, gibt es doppelt so viele Fehlerquellen. Für Leute, die die Sprache kennen, ist es perfekt lesbar, und es ist sogar in unserem <i>Learning Perl</i> Kurs enthalten.

2voto

textral Punkte 989

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

Da sein Ansatz auf map Es funktioniert auch gut für Arrays, erfordert aber eine Kaskadierung map um ein temporäres Array zu erzeugen (andernfalls würde das Original verändert werden):

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X