Shift_JIS でもエラーにならない Perl 正規表現

Shift_JIS 正規表現のエラーの解決方法

正規表現に使用する前に、特殊文字をエスケープ(「\」を前に付けてその文字の特殊性を打ち消す)してやればよいわけです。

「申請書」のように含まれる特殊文字が「\」の場合、正規表現が「申\請書」となるようにしてやれば、消えてしまう「申」の後半の「\」の代わりに追加した「\」が入るので、これをエスケープできます。

#Shift_JIS でも期待通りマッチ
$teststr = '申請書';
$restr = '申\\請書'; #「\」が2つあるのは文字列指定時のエスケープ

print "$teststr MATCHED\n" if $teststr =~ /$restr/;

正規表現上の問題となる日本語文字中に含まれる特殊文字が、エスケープ用の特殊文字「\」である場合は上記のようにコード上見える形でのエスケープが可能ですが、「メール」の場合のように「 [ 」をエスケープしなければいけない場合、「ー」の前半1バイトと後半1バイトの間に「\」を挟むことはコード上は不可能です。

この場合、やはり正規表現で、正規表現文字列をエスケープしてやります。

#正規表現エスケープ用関数
sub esc4re{
    my $str = shift;
    $str =~ s/([\x21\x24-\x26\x28-\x2b\x2e\x2f\x3f\x40\x5b-\x5e\x7b-\x7d])/\\$1/g if $str;
    return $str;
}

#以下は全て意図どおりマッチ
$teststr = '電話';
$restr = &esc4re($teststr);
print "$teststr MATCHED\n" if $teststr =~ /$restr/;

$teststr = '申請書';
$restr = &esc4re($teststr);
print "$teststr MATCHED\n" if $teststr =~ /$restr/;

$teststr = 'メール';
$restr = &esc4re($teststr);
print "$teststr MATCHED\n" if $teststr =~ /$restr/;