• ベストアンサー

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文字ずつ見ていけばいいんですが、動作速度のカラミもあって、正規表現の使用はやめたくありません。  どうにか、正規表現だけでこの問題を回避する方法はないでしょうか。 

質問者が選んだベストアンサー

  • ベストアンサー
  • leaz024
  • ベストアンサー率75% (398/526)
回答No.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 は不要です。

参考URL:
http://www.din.or.jp/~ohzaki/perl.htm#JP_Match
noname#25358
質問者

お礼

 ありがとうございます。  正規表現にももう慣れたつもりでしたが、まだまだ俺の知らない記述法があるもんですね(^_^;  研究してみます。  それと、e がついてたのは馬鹿バグでした(^^;゜。

その他の回答 (1)

  • Dpop
  • ベストアンサー率51% (279/544)
回答No.1

一旦、EUCに変換してから、コンバートしてはどうでしょうか? %Tbl の内容が分からないので、単純にできるのかどうかは定かでは無いのでずか、SJISの文字区切りの問題が発生するのであれば、その部分だけEUCで処理する。ってのが定番な様な気がします。

noname#25358
質問者

お礼

 ありがとうございます。  そういえば別のところでもそれやってたよーな……。  試してみますね。

関連するQ&A