CSVと文字コード変換

サーバの環境をUTF-8にしたとして、クライアントはShift-JISでCSVをやり
とりしたい場合がある。

というわけで試してみました。現状は以下の通り

SJIS-UTF変換は基本OK
CSVデータにカンマ込み、ダブルクォート込みのデータがあっても標準ライブラリでパース出来る
パフォーマンスが悪いという話が多い。テスト次第で他の方法を検討か?

文字コード変換もCSVパースも標準のライブラリを使用します。

  • NKFライブラリ
  • CSVライブラリ

SJISCSVファイルをパースしてサーバコンソールに表示するサンプルスクリプト

require "csv"
require "nkf"

open("test.csv").each {|line|
  CSV.parse(line).each{|row|
    puts NKF::nkf("-w", row.to_s)    #-wでUTF-8に変換、Shift-JISにする場合は-s
  }
}

テストデータCSV

テスト,"32,64","1""234""564"

実行結果

[littlestarling@test ~]$ ruby csvTest.rb
テスト32,641"234"564

パースの結果は配列になっているので変換時にto_sしてあげる必要がある
とか、そもそもデータの取り方でrow["name"]みたいなやり方にするとか
少々手間は入ると思いますが一応変換は出来るということまで確認しました。

  • 改行するとどうなる? →エラーはきます。

改行データつきCSV

"テス
ト","32,64","1""234""564"

実行結果

[littlestarling@test ~]$ ruby csvTest.rb
/usr/lib/ruby/1.8/csv.rb:607:in `get_row': CSV::IllegalFormatError (CSV::IllegalFormatError)
        from /usr/lib/ruby/1.8/csv.rb:556:in `each'
        from /usr/lib/ruby/1.8/csv.rb:127:in `collect'
        from /usr/lib/ruby/1.8/csv.rb:127:in `parse'
        from csvTest.rb:6
        from csvTest.rb:5:in `each'
        from csvTest.rb:5

このあたりもう少し調査すればなんとかなるのか、こういう制約がある
と思った方がいいのかはちょっとわかりませんでした。

で、CSVParserで書いた場合。

require "nkf"
require "csvparser"

csv = CSVParser.new_with_file "test.csv"

csv.each do |line|
  puts NKF::nkf("-w",  line.to_s)
end

実行結果

[littlestarling@test ~]$ ruby csvTest.rb
"テス
ト","32,64","1""234""564"

ぱちぱちぱち。