SIMEL
SIMEL

Reputation: 8939

Unrecognized escape \m passed through in regex error with PERL

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

Answers (3)

gangabass
gangabass

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

Rosh Oxymoron
Rosh Oxymoron

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

Gabriel Reid
Gabriel Reid

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

Related Questions