在 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 编码人员会知道并理解它,但它的透明度和可读性远不如您开始使用的两行复制和修改对联。
换句话说,做到这一点的好方法是你已经在做的方式。以可读性为代价的不必要的简洁不是胜利。
另一个 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
如果你用 编写 Perl use strict;
,那么你会发现单行语法是无效的,即使在声明时也是如此。
和:
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.
相反,您一直在使用的语法虽然更长,但在语法上是正确的使用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";
我讨厌 foo 和 bar .. 谁在编程中想出了这些非描述性的术语?
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
如果我只是在oneliner中使用它,怎么样,sprintf("%s", $oldstring)