我想找到并替换多个存储内容的标量变量(每个字符串的内容会有所不同)因此我需要为两个变量插入两行来进行相同的替换。
$str1=~s/\_/&underscore\;/g;
$str1=~s/\^/&carrot\;/g;
$str2=~s/\_/&underscore\;/g;
$str2=~s/\^/&carrot\;/g;
是否有可能在一次拍摄/同时更换所有要更换的琴弦。请注意,内容会因字符串而异。 (可能是我问问题的方式是小孩,但是我正在替换超过200行,但试图减少编码行)
答案 0 :(得分:6)
您可以将变量置于for
循环中,该循环将依次为每个变量添加$_
。请注意,下划线或分号都不需要在正则表达式模式中进行转义
for ( $str1, $str2 ) {
s/_/&underscore;/g;
s/\^/&carrot;/g;
}
然而,这两者都是非标准实体。你自己宣布过吗?你可能意味着caret
而不是carrot
,这是一种蔬菜!我看到它叫^
,但我认为这也是非标准的。您始终可以使用^
(和_
作为下划线)
答案 1 :(得分:1)
最简单的方法可能是定义映射规则,从这些规则构建正则表达式,以及应用它们的提供函数。这是对它的抨击:
my %map = (
"_" => "&underscore;",
"^" => "⁁",
);
sub apply_map {
$_[0] =~ s/(${\
join "|", map quotemeta, keys %map
})/$map{$1}/g;
}
apply_map $str1;
apply_map $str2;
并且,借用Borodin的答案,将地图应用于更少语句中的多个字符串:
foreach ($str1, $str1) {
apply_map $_;
}
或者,修改apply_map以获取多个参数:
sub apply_map {
s/(${\
join "|", map quotemeta, keys %map
})/$map{$1}/g foreach @_;
}
apply_map $str1, $str2;
请注意quotemeta
。这可以防止映射键中的任何特殊字符影响正则表达式的行为。我也使用${\ .. }
语法在s///
中插入表达式,但是构建单独的模式字符串可能更清楚。如果您要替换的所有内容都是一个字符长,则可以加入''
并使用字符类(例如[_^]
),而不是加入|
。