元の文字列を保持したまま、文字列に対して Perl 置換を実行するにはどうすればよいですか?
質問
Perl で、正規表現を使用して文字列の置換を実行し、元の値を変更せずにその値を別の変数に保存する良い方法は何ですか?
通常、文字列を新しい変数にコピーして、それをバインドします。 s///
新しい文字列の置換を行う正規表現ですが、これを行うより良い方法があるかどうか疑問に思っていました。
$newstring = $oldstring;
$newstring =~ s/foo/bar/g;
解決
これは、元の文字列を変更せずに文字列の変更されたコピーを取得するために私が常に使用してきたイディオムです。
(my $newstring = $oldstring) =~ s/foo/bar/g;
Perl 5.14.0 以降では、新しい /r
非破壊置換修飾子:
my $newstring = $oldstring =~ s/foo/bar/gr;
注記:上記の解決策は、 g
あまりにも。これらは他の修飾子とも併用できます。
他のヒント
声明:
(my $newstring = $oldstring) =~ s/foo/bar/g;
これは以下と同等です:
my $newstring = $oldstring;
$newstring =~ s/foo/bar/g;
あるいは、Perl 5.13.2 以降では、次のように使用できます。 /r
非破壊的な置換を行うには:
use 5.013;
#...
my $newstring = $oldstring =~ s/foo/bar/gr;
下 use strict
, 、 言う:
(my $new = $original) =~ s/foo/bar/;
その代わり。
ワンライナーの解決策は、優れたコードというよりも、つまらないものとして役に立ちます。優れた Perl コーダーはそれを知っており、理解するでしょうが、最初に始めた 2 行のコピーと変更の対句に比べて、透明性と可読性がはるかに劣ります。
言い換えれば、これを行うための良い方法は、あなたのやり方です すでに している。読みやすさを犠牲にして不必要に簡潔にすることは成功とは言えません。
5.14 より前の別のソリューション: http://www.perlmonks.org/?node_id=346719 (japhy の投稿を参照)
彼のアプローチでは、 map
, 、配列でもうまく機能しますが、カスケードが必要です map
一時的な配列を生成します (そうしないと、元の配列が変更されてしまいます)。
my @orig = ('this', 'this sucks', 'what is this?');
my @list = map { s/this/that/; $_ } map { $_ } @orig;
# @orig unmodified
私はフーとバーが嫌いです..とにかく、プログラミングでこのような説明的ではない用語を誰が考え出したのでしょうか?
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
Perl を書く場合 use strict;
, と宣言した場合でも、その 1 行の構文は無効であることがわかります。
と:
my ($newstring = $oldstring) =~ s/foo/bar/;
得られるもの:
Can't declare scalar assignment in "my" at script.pl line 7, near ") =~"
Execution of script.pl aborted due to compilation errors.
代わりに、これまで使用してきた構文は、1 行長くなりますが、構文的には正しい方法です。 use strict;
. 。私にとって、使用するのは、 use strict;
それは今ではただの習慣です。自動的にやりますよ。誰もがすべき。
#!/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";