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/;