WindwosのRubyでCSVを扱おうとしたら、たぶん文字コード系のエラーが出たときの対処法

ある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検索

`=~’:+invalid+byte+sequence+in+UTF-8+(ArgumentError)

結果、読み込むときに変換が必要みたいです。

  • 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ができないので対処方法がわからない。
  • 文字コードの把握
タイトルとURLをコピーしました