読者です 読者をやめる 読者になる 読者になる

NKF の --cp932 オプションがおかしい

いや --cp932 の本来の動きを知らないので、おかしいというより自分の期待通りではないというべきかもしれません。

文字コードの変換の際、JIS 規格じゃなくて Windows がやっているような変換をして欲しいときに、--cp932 をつけとけば良きにはからってくれるんじゃないかなぁ…と漠然と思っていたのです。

UTF-8 から ISO-2022-JP への変換の場合、「-Wj --cp932」としておけばよいと思ってたらうまくいきません。梯子高を変換してみます。

$ ruby -rnkf -e 'puts NKF.nkf("-Wj --cp932", "\xe9\xab\x99").unpack("H*")'
1b242844747b1b2842

「1b24427c621b2842」を期待したのですが「1b242844747b1b2842」になってしまいました。これじゃアレなので見やすくしてみます。

期待 ESC $ B 7c 62 ESC ( B
結果 ESC $ ( D 74 7b ESC ( B

「ESC $ B」は ISO-2022-JPJIS X 0208、「ESC $ ( D」は ISO-2022-JP-1JIS X 0212 であることを意味してます。*1なお、--cp932 を外しても同じでした。

そういうもんだっけか…と思ったのですが、なんと nkf コマンドを使ってみたら期待通りに動いたのです。

$ printf "\xe9\xab\x99\n" | nkf -Wj --cp932 | od -tx1
0000000 1b 24 42 7c 62 1b 28 42 0a
0000011

ちなみに --cp932 を外してもやはり同じでした。

$ printf "\xe9\xab\x99\n" | nkf -Wj | od -tx1
0000000 1b 24 42 7c 62 1b 28 42 0a
0000011

ruby と nkf コマンドで動きが違うのは nkf のバージョンが違うためであることが疑われます。コマンドラインの nkf は 2.0.7 だったのに対し、ruby の nkf は 2.0.8 でした。

http://sourceforge.jp/projects/nkf/releases/?package_id=533 から nkf の色々なバージョンをダウンロードしてオプションを試してみました。

バージョン -Wj -Wj --cp932 -Wj --no-cp932 -W --oc=CP50220 -W --oc=CP50220 --cp932
2.0.7 ×
2.0.8 × × ×
2.0.9 × × ×

(○: JIS X 0208, ×: JIS X 0212

2.0.7 と 2.0.8 以降とで動きが変わっています。--cp932 オプションが怪しいです。--cp932 と --no-cp932 の動きを見ると、意味が逆になっているようにも見えます。

すべてのバージョンで期待通りなのは --oc=CP50220 オプションなので、これで行こうと思います。

あとで、梯子高以外も試してみようと思います。

*1:もちろん、梯子高は JIS にない文字であることは承知しているのですが、JIS X 0212 にならんでも…。