- 締切済み
rubyの見えない文字
こんばんは Ruby1.9.2のrails3.1.1を使用しています。 csvファイルをアップロードして、 data = param[:file].read.encode("UTF-8","UTF-8", :invalid => :replace, :undef => :replace, :replace => '').read.encode("UTF-8", :invalid => :replace, :undef => :replace, :replace => '?') のように読み込みまして、最初の1行の最初の要素が"code"でした。そこで、 data[0][0] == "code" としましたところ、falseが出力されました。両方とも文字コードはUTF-8で"code"なのですが、調査したところ data[0][0]length #=> 5 "code".length #=> 4 という違いが見つかりました。 この読み込みデータの見えない文字はなんなんでしょうか。 また、これを取り除く方法は何かありませんでしょうか。よろしくお願いします。 参考 data = param[:file].read.encode("UTF-8", :invalid => :replace, :undef => :replace, :replace => '').read.encode("UTF-8", :invalid => :replace, :undef => :replace, :replace => '?') としたところ、"???code"、長さ7という結果になりました。
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- sholmes
- ベストアンサー率81% (89/109)
rails全然わからないので、以下は勘回答です。 使えなさそうだったら無視して下さい。 メソッドチェーン眺める限り、 param[:file] とやらでFileのインスタンスとってる気がします。 (なぜそのあとread.encodeを2回続けているのかとかわかりませんが・・・) その後readしてしまってますが、こうすると綺麗にBOM削るのは難しそうなので、IO/File時点で削るというのが第一感です。 日本語マニュアルにはまだ反映されていないっぽいんですが、下記のドキュメントにこの記法があります。 http://www.ruby-doc.org/core-1.9.3/Kernel.html#method-i-open たぶん、次の検討を経て取り入れられたものです。 http://bugs.ruby-lang.org/issues/1951 結論を言うと、頭の方の param[:file].read.encode("UTF-8","UTF-8", :invalid => :replace, :undef => :replace, :replace => '') といったあたりを param[:file].set_encoding("BOM|UTF-8","UTF-8", :invalid => :replace, :undef => :replace, :replace => '').read こんな感じに書き換えて動きませんかね?という・・・ 的外れだったらすみません。
- ibara994
- ベストアンサー率75% (9/12)
それはBOMだと思います UTF-8のBOMは3バイトで 0xEF 0xBB 0xBF です
お礼
重要な足がかりをありがとうございました。
補足
調査したところ、確かにBOMでした。 しかし、すっきりした取り除き方法は依然不明です。
- mudai_yeh
- ベストアンサー率0% (0/0)
IBM拡張文字あたりでは無いでしょうか? 具体的にどのような文字なのでしょうか?
補足
ご面倒をおかけします data[0][0].bytes.to_a[0] で文字コードを調べると「239」ということでした。
改行じゃなくて?
補足
説明不足でご迷惑をおかけします。 csvファイルの先頭は "code","name","kana" "01","北海道","ほっかいどう" ・・・ という感じになっています。 ちなみに、いま確認しましたら"01"はlength2で、2行目からは発生しませんでした。
お礼
とりあえず、 params[:f].read.encode("UTF-8", :invalid => :replace, :undef => :replace, :replace => '') で消えてくれるようになりました。 エラー処理扱いで釈然としませんが、袋小路です。 詳細な情報提供ありがとうございました。
補足
params[:file]の型には「set_encodeメソッド」はないようです。 また、params[:file]の型はActionDispatch::Http::UploadedFile のため、典型のopenメソッドが使えないようです。