- ベストアンサー
SJISに関する少々複雑な問題
Perl で、下記のようなプログラムを組みました。 $original =~ s/\x83[\x80-\x96]/$Tbl{$&}/eg; このとき連想配列のキーには、"\x83\x80" ~ "\x83\x96" に該当するSJISの文字が入っています。 つまり、この範囲の全角文字を、別の文字に変換する正規表現です。 ところが(^_^; このソースだと問題があって、"麻雀" という文字をこの正規表現にかけると、おかしくなります。 "麻雀" の文字コード "\x96\x83""\x90\x9d" のうち、「麻のテイルと雀のヘッド」の2文字がこの範囲チェックに引っかかってしまい、結果、本来は変換されてほしくない文字である "麻雀" は、"夢・"("\x96\xb2\x9d") という変な文字に変換されてしまうんです。 "\x83\x90" という全角文字が "\xb2" という半角文字に置き換わる構造になっているからです。 前方から1文字ずつ見ていけばいいんですが、動作速度のカラミもあって、正規表現の使用はやめたくありません。 どうにか、正規表現だけでこの問題を回避する方法はないでしょうか。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
この手のパターンは、EUCに変換しただけではうまく行かない場合があります。 詳しくはこちら http://www.din.or.jp/~ohzaki/perl.htm#JP_Match このページでEUCの場合の対処方法が書かれていますが、同様の方法でShiftJISでも対処可能です。 my $re_sjis = qr/(?:[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC]|[\x00-\x7F\xA1-\xDF])/; $original =~ s/\G($re_sjis*?)(\x83[\x80-\x96])/$1$Tbl{$2}/g; 要するに、「前方から1文字ずつ見ていけばいいんですが」を正規表現で書けばいいということです。 ちなみに REPLACEMENT にコードがない場合、オプションの e は不要です。
その他の回答 (1)
- Dpop
- ベストアンサー率51% (279/544)
一旦、EUCに変換してから、コンバートしてはどうでしょうか? %Tbl の内容が分からないので、単純にできるのかどうかは定かでは無いのでずか、SJISの文字区切りの問題が発生するのであれば、その部分だけEUCで処理する。ってのが定番な様な気がします。
お礼
ありがとうございます。 そういえば別のところでもそれやってたよーな……。 試してみますね。
お礼
ありがとうございます。 正規表現にももう慣れたつもりでしたが、まだまだ俺の知らない記述法があるもんですね(^_^; 研究してみます。 それと、e がついてたのは馬鹿バグでした(^^;゜。