RubyでJISの半角カナを文字コード変換すると文字化ける
Rubyで半角カナ入りのテキストを、(NKFとかKconvで)JIS(ISO-2022-JP)からほかの文字コードに変換すると、文字化ける場合があったので、調べてみました。
まずISO-2022-JPで半角カナを表す正式な方法はないようです。非公式な方法として
- ESC ( Jを使って8ビットコードを使用する方法
- SO/SIを使って7ビットコードを使用する方法
- ESC ( I を使って7ビットコードを使用する方法
があるらしいです(この辺参照)。
で、問題のテキスト(具体的にはcottonから送信されたIRCのメッセージ)の半角カナは1番目の方法を使ってるんですが、NKFは3番目の方法にしか対応してないらしく、文字化けたのでした*1。
というわけでお手軽な対処法として
s= s.gsub(/\e\(J/n, "\e(I").unpack("C*"). map(){ |c| (c & 0x7f) }.pack("C*")
というコード(ちょっと効率悪いですが)で1番目の方式を3番目の方式に変換してからNKFをかけたところ、うまくいきました。
ちなみにKconvで変換すると半角カナが全角になるので、半角のままにしたい場合はNKF.nkf("-eJx", s)(EUCにする場合)とかやる必要があります。