2008-08-22 87 views
146

在Perl中,使用正则表达式对字符串执行替换并将值存储在其他变量中而不更改原始值的好方法是什么?如何在保留原始字符串的情况下对字符串执行Perl替换?

我通常只是将字符串复制到一个新的变量,然后绑定到s///正则表达式替换新的字符串,但我想知道是否有更好的方法来做到这一点?

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

回答

203

这是我一直使用得到一个字符串的修改副本,而不改变原有的成语:

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

用Perl 5.14.0或以后,你可以使用新的/rnon-destructive substitution modifier:

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

注:上述解决方案的工作没有g了。他们也与其他修饰符一起工作。

+5

是否使用严格。变量的最小范围++ – ysth 2008-09-19 06:11:32

+0

我在想,如果像`my $ new = $ _ for $ old =〜s/foo/bar;`会起作用吗? – Benoit 2014-04-30 17:11:26

+1

@Benoit,我相信你的意思是`s/foo/bar /对于我的$ newstring = $ oldstring;`它可以工作,但它远远不够。 – ikegami 2017-02-22 16:41:34

41

声明:

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

等同于:

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

另外,像Perl 5.13.2,你可以用/r做无损替代:

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

你忘了顶级正则表达式中的`g`吗? – mareoraft 2014-09-10 21:23:52

-1

如果你使用use strict;编写Perl,那么你会发现一行代码syn即使宣布,税收也是无效的。

有了:

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"; 
+0

如果您使用警告;而不是使用-w,您可以获得更大的控制权:例如,如果您想暂时关闭代码块中的警告。 – 2009-10-21 13:51:41

19

use strict,说:

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

代替。

8

单线解决方案作为shibboleth比优质代码更有用;好的Perl编程人员会知道它并理解它,但它比你开始使用的双行复制和修改联系更不透明和可读。

换句话说,做这件事的一个好方法就是你已经这样做的方式。以可读性为代价的不必要的简洁是不成功的。

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 
0

另一个前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 
相关问题