あるCSVファイル「test.csv」、これはおそらくANSI(shift_jisかCP932)で作られている。Rubyは基本というか私自身もUTF-8しか扱いたくない。
#このコードはエラーが出ます… #test.csvの中身は公表できないです… require "csv" csvfile = CSV.read("test.csv") csvfile.map! do |line| line.encode("utf-8") end p csvfile
このtest.csvを読み込んで、表示させようとすると、「invalid byte sequence in UTF-8 (ArgumentError)」というエラーが出る。「UTF-8」という記載があるので十中八九、文字コード系のエラーだよね?ということで検索しました。
Google検索
結果、読み込むときに変換が必要みたいです。
- CSV.read(“test.csv”, encoding: ‘Shift_JIS:UTF-8’)
- CSV.foreach(“test.csv”, encoding: ‘Shift_JIS:UTF-8’)
のどっちでもいいみたいです。
対応方法
私はCSV.read派ですので、以下のように対応しました。
「encoding: “cp932:utf-8″」の部分です。この1行追加だけです。
require "csv" csv_file = CSV.read("test.csv", encoding: "cp932:utf-8") p csv_file p csv_file.count p csv_file.class #csv_file = CSV.read("test.csv", encoding: "cp932:utf-8", undef: :replace, invalid: :repalce, replace: "?") #↑これはできません
参考にさせていただきましたサイトです。
【参考】CSVファイルをインポートするときにinvalid byte sequence in UTF-8エラーがでる場合の対処法
通常CSVはExcelとかでも見れるようにShift-jisとかにしているので、データを抽出する際に文字コードを変更してあげるようにする
↓
require 'csv' CSV.foreach('db/hogehoge.csv', encoding: 'Shift_JIS:UTF-8') do |row| ~ ~
【参考】文字コードにはマジ、マジで気をつけよう(ていうか不注意)
ちなみに文字コードを考慮してcsvを開く場合はこちらです。
↓
~ [76] pry(main)> csv_data = CSV.read("data/test4.csv", headers: true, encoding: "CP932:UTF-8") => #<CSV::Table mode:col_or_row row_count:1121> ~
文字コードがわからないときは?
上記のように、Shift_JISやcp932などと検討がつくからいいけど、他者からもらったファイルの文字コードがわからない場合はどう対応すればいいか?
というのは、Shift_JISのファイルなのに、何も考慮せず読み込んでencodingで値をとったら、UTF-8と表示される。これはなぜだろう?
また、CSVライブラリにはencodingのオプションに、「undef: :replace」「replace」の実装がないようでです。打つ手なしか?
#test.txtはShift_JISのファイルだとする。でも「UTF-8」と表示される file = File.read("test.txt") p file.encoding #<Encoding:UTF-8>
なぜ?
これまだ解決できていません。
CSVライブラリではreplaceの機能がない!?
replace解決
Google検索「CSV replace ruby」
CSV.open で Encoding::UndefinedConversionError になる場合
こちらのサイトでは一度文字列にして、replaceオプションを使用して、csvに戻しているというイメージでしょうか。
文字コードについて
自分が思っているより単純じゃない気がしてきました。結構ヘビーですね。ただメソッドに引数指定して実行ってわけじゃなさそうですね…。
以下2点が解決できていません。
- undefとinvalidが起きたときにreplaceができないので対処方法がわからない。
- 文字コードの把握