Rubyで全角英数字を半角英数字にnkfで変換する時の落とし穴
RubyでUTF-8文字列の全角英数字の表記揺れを統一したいとき、 気をつけないと希に文字化けする事象を見つけたのでメモします。
NKFを用いて全角英数字→半角英数字に変換する方法
ググるとよく出てくる方法は次の通りです。
もちろん、問題なく普通に動きます。
$ pry [1] pry(main)> require 'nkf' => true [2] pry(main)> NKF.nkf('-m0Z1 -w', "Ruby−2.2") => "Ruby-2.2"
ここでWindowsの機種依存文字が混じるとどうなるでしょうか。
pry(main)> NKF.nkf('-m0Z1 -w', "ルビー Ⅱ") => "ルビー Ⅱ" pry(main)> NKF.nkf('-m0Z1 -w', "ルⅡ") => "繝ォ竇。" pry(main)> NKF.nkf('-m0Z1 -w', "Ruby Ⅱ") => "Ruby 竇。"
なんと、文字の組み合わせ次第では化けてしまいます。これは気づきにくいですね。
調べると、機種依存文字に関するオプションを発見しました。
--cp932 Windows の機種依存文字(〜−¢£¬|など)をUnicodeに変換するときに文字化けしないようにする。
引用元: http://www003.upp.so-net.ne.jp/NAMBOKU/ruby/ruby0352.html
試しにこの引数を追加すると、期待通りの動作とは・・・なりません!!!
まあ元がUTF-8なのでcp932を指定するのも変だとはうすうす思っておりましたが。
pry(main)> NKF.nkf('-m0Z1 -w --cp932', "ルビー Ⅱ") => "ルビー Ⅱ" pry(main)> NKF.nkf('-m0Z1 -w --cp932', "ルⅡ") => "繝ォ竇。" pry(main)> NKF.nkf('-m0Z1 -w --cp932', "Ruby Ⅱ") => "Ruby 竇。"
ここで1度、引数のそれぞれの意味を見てみましょう。
引数 | 意味 |
---|---|
-m0 | MIME(電子メール用のフォーマット)に変換しない (nkfはこのオプションを指定しない限り、MIMEに変換する処理を行う)。 |
-Z1 | 全角スペースを半角スペース1個に変換する。 |
-w | 出力ファイルの文字コードをUTF-8(BOMなし)とする(-W80とおなじ)。 |
引用元: http://www003.upp.so-net.ne.jp/NAMBOKU/ruby/ruby0352.html
ここで気づくのは、入力文字コードの指定が行われていないことです。
このため、先ほどのcp932のオプションはShift_JISでの読み込み時に使うものであったことが分かりました。
そこで、次のように-wと-Wをそれぞれ指定してみましょう。
引数 | 意味 |
---|---|
-m0 | MIME(電子メール用のフォーマット)に変換しない (nkfはこのオプションを指定しない限り、MIMEに変換する処理を行う)。 |
-Z1 | 全角スペースを半角スペース1個に変換する。 |
-W | 入力ファイルの文字コードをUTF-8(BOMなし)とする(-W80とおなじ)。※追加※ |
-w | 出力ファイルの文字コードをUTF-8(BOMなし)とする(-W80とおなじ)。 |
pry(main)> NKF.nkf('-m0Z1 -W -w', "ルビー Ⅱ") => "ルビー Ⅱ" pry(main)> NKF.nkf('-m0Z1 -W -w', "ルⅡ") => "ルⅡ" pry(main)> NKF.nkf('-m0Z1 -W -w', "Ruby Ⅱ") => "Ruby Ⅱ"
無事に期待通りの動作となりました。
まとめ
rubyでnkfを利用するときは、入力文字コードを自動判定ではなくしっかりと指定しましょう!
引数 | 意味 |
---|---|
-S | 入力ファイルの文字コードをshift_jisとする。 |
-E | 入力ファイルの文字コードをEUC-JPとする。 |
-J | 入力ファイルの文字コードをISO-2022-JP(いわゆるjisコード)とする。 |
-W | 入力ファイルの文字コードをUTF-8(BOMなし)とする(-W80とおなじ)。 |
あわせて読みたい
半角英数字に変換し、さらに機種依存文字も変換したいケースでは、
NKFではなく次のページで紹介されているunicode gemが万能でお勧めです。
文字列の表記揺れをUnicode正規化で簡単に解決する方法
http://qiita.com/y-ken/items/d08eb7f66c8fb2fa7d21
プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB PRESS plusシリーズ)
- 作者: 矢野啓介
- 出版社/メーカー: 技術評論社
- 発売日: 2010/02/18
- メディア: 単行本(ソフトカバー)
- 購入: 34人 クリック: 578回
- この商品を含むブログ (130件) を見る