ある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ができないので対処方法がわからない。
- 文字コードの把握