LoginSignup
3
3

More than 5 years have passed since last update.

(跡地)CSVと文字エンコードで悩んで、後からUTF-8に変換した、ruby力低い話

Last updated at Posted at 2016-05-26

 注意

内容がグダグダなので、以下に書き直しました。

Ruby文字エンコードに悩まされ、直接指定やnkfによる推測などを試した
http://qiita.com/rojiuratech/items/9d40cb294eb08f2204ac

概要

RubyでUTF-8ではないCSVを読み込み、取り扱う話。
直接読み込もうとしたらダメだったが。一旦変換掛けててから扱えば
すんなりと通った。

環境

  • ruby 2.2.3

CSVライブラリで、UTF-8でないCSVが読み込めない。

他部門はWindowsPCを使っており、MS-ExcelでCSVファイルを保存しようとすると、Shift_JISで保存されてしまいます。

ところが、Rubyに最初からあるCSVクラスで、UTF-8以外のファイルを開こうとすると・・・。

エラー抜粋
/ruby/2.2.0/csv.rb:2007:in `=~': invalid byte sequence in UTF-8 (ArgumentError)
rom read_csv.rb:3:in `<main>'

などというエラーが発生。

エラーが発生したソースファイル
require "csv"

data = CSV.read(ARGV[0])

data.each do |str|
  p str.toutf8
end

UTF-8的に正しくないバイトシーケンスが混じっていて、そこでコケたようです。

この辺りは下記リンクでも述べられています。

sonnets:blog
Ruby の invalid byte sequence in UTF-8 例外を encode("UTF-8", "UTF-8") で回避するのはおかしいよ、という話

過去やっていた、ひどい対応

CSVファイルをエクセルで読み込んで、それをxlsx形式で保存し、
roo(ruby上でスプレッドシートを扱うGem)を使って読み込みインポート・・・。などの、やむをえないけど意識低いことをやってた。

先日のkawasaki.rbで、文字コードの変換話が出た

パーフェクトRubyで、文字列の文字コードを変換して、同じ値か比較する・・・。みたいな話が出てきた。

なら、文字エンコードを変換して与えれば良いのでは?!

方針

読み込むCSVファイルは、ただのテキストファイルとして読み込む。
この時、文字コードをUTF-8にして読む。
UTF-8に変換後のデータを、CSVクラスで扱う。

追記! 正しくは File.read です。

CSVファイル読み込み、変換スクリプト
# 使用するライブラリを読み込む
require 'kconv'
require 'csv'

#読み込み対象ファイルのパスを受け取る
read_file = ARGV[0]

# 読み込み対象ファイル
raw_str = ""

#読み込み対象のファイルを、一度に読み込む
raw_str = File.read(read_file)


# raw_str = File.open(read_file)
# 読み込んだものを配列化
mod_str = CSV.parse(raw_str)

#1行ずつ表示する
i = 0
mod_str.each do |str|
  p i
  p str
  i = i + 1
end

ためしによみこむファイル

読み込み対象
品名,種類,値段
棍棒,武器,60
薬草,drug,10
毒草,drug,1
,(空欄),2000
いつもの,何か,45くらい
,,
実行結果
$ ruby read_sjis.rb fake_euc.csv
0
["品名", "種類", "値段"]
1
["棍棒", "武器", "60"]
2
["薬草", "drug", "10"]
3
["毒草", "drug", "1"]
4
[nil, "(空欄)", "2000"]
5
["いつもの", "何か", "45くらい"]
6
[nil, nil, nil]

このやり方が真価を発揮するのは・・・

セル内改行を含むケース。だと思う。

3
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3