我正在尝试使用Regex和包含更改的哈希表来更改一行。我正在使用下一个代码进行更改:
foreach $key (keys %{$hash{$sub_hash}}){
$line =~ s/$key/$hash{$csub_hash}{$key}/g;
}
我的哈希是:
$hash{sub_hush_a}={
"\\mi2ie..." => "\\RSUop...",
"iereset..." => "\\agres...",
};
问题在于,对于数据集中的第一对,当它发生变化时,它会放置\\
而不是\
,而对于第二对,只会按预期放置一个。
它也给了我错误:
Unrecognized escape \m passed through
。
有什么问题?
澄清:名称中的点不在程序中,名称比我放的长,并且都只包含字母和数字。这里的点是为了缩短。
修改
问题修复,(双\
和错误消息)如果我将第一对更改为:
"mi2ie..." => "RSUop...",
(删除\\
)。
但我仍然想知道问题是什么,因为将来我可能需要添加可能导致问题的其他值。
答案 0 :(得分:6)
您遇到此问题,因为您的字符串在Regex 中将序列视为特殊序列。所以你需要转义/引用这个序列。这是Perl所谓的 Dirty Dozen :
\ | ()[{^ $ * +?
这将解决它(\Q..\E
将引用此类元字符):
foreach $key (keys %{$hash{$sub_hash}}){
$line =~ s/\Q$key\E/$hash{$csub_hash}{$key}/g;
}
答案 1 :(得分:0)
看起来你遇到了问题,因为你使用字符串文字作为正则表达式,并且在字符串文字中使用反斜杠的方式不同于在正则表达式中使用反斜杠。
使用qr
运算符(http://perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operators),可以通过在散列中存储正则表达式而不是字符串文字来解决此问题。
答案 2 :(得分:0)
my $line = 'test\mi2ie...test';
sub replace($$$) {
my ($str, $what, $replacement) = @_;
my $pattern = quotemeta($what);
$str =~ s/$pattern/$replacement/g;
return $str;
}
my %hash;
my $sub_hash = "test";
$hash{$sub_hash} = {
'\mi2ie...' => '\RSUop...',
'iereset...' => '\agres...',
};
while (my ($key, $value) = each %{$hash{$sub_hash}}) {
$line = replace($line, $key, $value);
}
print "$line\n";