在Perl中,使用正则表达式对字符串执行替换并将值存储在另一个变量中而不更改原始值的好方法是什么?
我通常只是将字符串复制到一个新变量,然后将其绑定到新字符串上替换的s///
正则表达式,但我想知道是否有更好的方法来执行此操作?
$newstring = $oldstring;
$newstring =~ s/foo/bar/g;
答案 0 :(得分:230)
这是我用来获取字符串的修改副本而不改变原始字体的习语:
(my $newstring = $oldstring) =~ s/foo/bar/g;
在perl 5.14.0或更高版本中,您可以使用新的/r
non-destructive substitution modifier:
my $newstring = $oldstring =~ s/foo/bar/gr;
注意:上述解决方案也可以在没有g
的情况下运行。它们也适用于任何其他修饰符。
答案 1 :(得分:42)
声明:
(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;
答案 2 :(得分:20)
在use strict
下,说:
(my $new = $original) =~ s/foo/bar/;
代替。
答案 3 :(得分:9)
单线解决方案作为一个shibboleth比良好的代码更有用;好的Perl程序员会知道它并理解它,但它比你刚开始的两行复制和修改联接更不透明和可读。
换句话说,做到这一点的一个好方法就是你已经这样做了。以可读性为代价的不必要的简洁并不是一种胜利。
答案 4 :(得分:1)
我讨厌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
答案 5 :(得分:1)
另一个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
答案 6 :(得分:0)
如果我只是在 oneliner 中使用这个,怎么样,sprintf("%s", $oldstring)
答案 7 :(得分:-1)
如果你用use strict;
编写Perl,那么你会发现一行语法无效,即使在声明时也是如此。
使用:
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";