提问人:kaybenleroll 提问时间:8/23/2008 最后编辑:the Tin Mankaybenleroll 更新时间:5/13/2021 访问量:242772
如何在保留原始字符串的同时对字符串执行 Perl 替换?
How do I perform a Perl substitution on a string while keeping the original?
问:
在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
也可以看看: perldoc perlrequick
:Perl 正则表达式快速入门
评论
my $new = $_ for $old =~ s/foo/bar;
s/foo/bar/ for my $newstring = $oldstring;
声明:
(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;
评论
g
如果你用 编写 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";
评论
use warnings;
-w
在 下,说:use strict
(my $new = $original) =~ s/foo/bar/;
相反。
单行解决方案作为 shibboleth 比好的代码更有用;优秀的 Perl 程序员会知道并理解它,但它的透明度和可读性远不如你开始的两行复制和修改对联。
换句话说,做到这一点的一个好方法是你已经这样做的方式。以牺牲可读性为代价的不必要的简洁并不是一个胜利。
评论
我讨厌 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
评论
=~ s
newword donotnewword newword donotnewword newword donotnewword
foo
bar
另一个 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
如果我只是在 oneliner 中使用它,怎么样,sprintf("%s", $oldstring)
评论