有没有办法替换字符串中的多个字符串?
例如,我有字符串hello world what a lovely day
,我想用其他内容替换what
和lovely
。
$sentence = "hello world what a lovely day";
@list = ("what", "lovely"); # strings to replace
@replist = ("its", "bad"); # strings to replace with
($val = $sentence) =~ "tr/@list/@replist/d";
print "$val\n"; # should print "hello world its a bad day"..
为什么它不起作用的任何想法?
感谢。
答案 0 :(得分:12)
首先,tr
不起作用;有关详细信息,请参阅perldoc perlop
,但tr
会进行音译,与替换非常不同。
为此,更正确的替换方法是
# $val
$val =~ s/what/its/g;
$val =~ s/lovely/bad/g;
请注意,“同时”更改相当困难,但我们可以这样做,例如,
%replacements = ("what" => "its", "lovely" => "bad");
($val = $sentence) =~ s/(@{[join "|", keys %replacements]})/$replacements{$1}/g;
(当然,可能需要使用元字符替换字符串进行转义。)
这仍然只是在一个非常松散的意义上同时发生,但在大多数情况下,它确实表现为一次性完成替换。
此外,将"what"
替换为"it's"
而不是"its"
更为正确。
答案 1 :(得分:6)
好吧,主要是它没有工作,因为tr///d
与您的请求无关(tr/abc/12/d
替换1,b替换为2,并删除c)。此外,默认情况下,数组不会以对您的任务有用的方式插入到正则表达式中。此外,如果没有散列查找或子程序调用或其他逻辑,您无法在s///
操作的右侧做出决策。
要回答标题中的问题,您可以同时执行多次替换 - 呃,方便连续 - 以这种方式:
#! /usr/bin/env perl
use common::sense;
my $sentence = "hello world what a lovely day";
for ($sentence) {
s/what/it's/;
s/lovely/bad/
}
say $sentence;
做更像你在这里尝试的事情:
#! /usr/bin/env perl
use common::sense;
my $sentence = "hello world what a lovely day";
my %replace = (
what => "it's",
lovely => 'bad'
);
$sentence =~ s/(@{[join '|', map { quotemeta($_) } keys %replace]})/$replace{$1}/g;
say $sentence;
如果你要做很多这样的替换,首先'编译'正则表达式:
my $matchkey = qr/@{[join '|', map { quotemeta($_) } keys %replace]}/;
...
$sentence =~ s/($matchkey)/$replace{$1}/g;
编辑:
为了扩展我对阵列插值的评论,您可以更改$"
:
local $" = '|';
$sentence =~ s/(@{[keys %replace]})/$replace{$1}/g;
# --> $sentence =~ s/(what|lovely)/$replace{$1}/g;
这里没有改进的东西,实际上,虽然如果你已经拥有数组中的键,可能会有所改进:
local $" = '|';
$sentence =~ s/(@keys)/$replace{$1}/g;