假设我想用“橙色”替换“apple”这个词,用“apple”替换“orange”这个词,我怎么用Perl通过正则表达式做到这一点?
这是我的代码,我没有运气:
while (<MYFILE>) {
if (/apple/i) {
s/$&/orange/i;
}
if(/orange/i) {
s/$&/apple/i;
}
}
上面的代码可以工作我想如果有某种方法来终止if函数,如果它是成功的,并且不再执行代码强制它返回到while循环。但我确定这是一种简单的正则表达方式。
答案 0 :(得分:7)
首先,从不使用$&
变量:它会降低正则表达式引擎的速度。而且,你不需要它;这相当于你当前的循环体:
s/apple/orange/i;
s/orange/apple/i;
但是,我们必须增加两个:
/g
标志来实现这一点。我们可以通过使用将匹配的字符串映射到替换的哈希来实现:
my %replacement = (
apple => 'orange',
orange => 'apple',
);
while (<>) {
s/(apple|orange)/$replacement{lc $1}/ig;
print;
}
lc
小写匹配的字符串;这是必要的,以便将Apple
替换为orange
。通过删除不区分大小写的匹配并将Orange
和Orange
添加到替换哈希,可以实现保留外壳(以便我们获得Apple
)。
现在,如果你的哈希有大量的替换,我们不想手动编写正则表达式(只是很多静态替代)。我们可以从哈希中创建正确的正则表达式,如
my $re = join '|', map quotemeta, keys %replacement;
while (<>) {
s/($re)/$replacement{$1}/g;
}
quotemeta
转义特殊字符,以便您可以按字面匹配任意字符串。
答案 1 :(得分:3)
my %look = (
"apple" => "orange",
"orange" => "apple",
);
my $rx = join "|", keys %look;
while (<MYFILE>) {
s! ($rx) !$look{lc($1)}!xgi;
}