Reputation: 8939
I'm trying to change a line using Regex and a hash table containing the changes. I'm using the next code to change:
foreach $key (keys %{$hash{$sub_hash}}){
$line =~ s/$key/$hash{$csub_hash}{$key}/g;
}
And my hash is:
$hash{sub_hush_a}={
"\\mi2ie..." => "\\RSUop...",
"iereset..." => "\\agres...",
};
The problem is that for the first pair in the data set, when ever it changes it puts\\
instead of \
, and for the second one only puts one, as expected.
As well it gives me the error:
Unrecognized escape \m passed through
.
What is wrong?
clarification: the dots in the names are not there in the program, the names are longer than what I put, and are all containing only letters and digits. the dots are here in order to shorten.
EDIT:
The problem fixes, (the double \
and the error message) if I change the fist pair to:
"mi2ie..." => "RSUop...",
(remove the \\
).
But I still want to know what is the problem, as in the future I might need to add other values that may cause the problem.
Upvotes: 3
Views: 10903
Reputation: 10666
You have this issue because your strings have sequences treated as special in the Regex. So you need to escape/quote this sequences. Here is Perl so called Dirty Dozen:
\ | ( ) [ { ^ $ * + ? .
This will fix it (the \Q..\E
will quote such metacharacters):
foreach $key (keys %{$hash{$sub_hash}}){
$line =~ s/\Q$key\E/$hash{$csub_hash}{$key}/g;
}
Upvotes: 7
Reputation: 21045
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";
Upvotes: 0
Reputation: 2536
It looks like you're running into problems because you're using string literals as a regexp, and using backslashes in a string literal is interpreted differently than using backslashes in a regexp.
You can get around this by storing regexps in your hash instead of string literals, using the qr
operator (http://perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operators).
Upvotes: 0