Ruby, Groovy, Scala での Excel準拠 CSV ファイルのパース処理 - opencsv使用、Iterator.continually() 等

Excel の仕様に準拠した以下のような CSV ファイル(改行・カンマ・ダブルクォーテーションを要素内に含む)をパースし、第1・3の要素を標準出力に出力するサンプルを Ruby、Groovy、Scala で作成してみました。

CSVファイル例 test.csv
1,テスト1,"改行
含み"
2,test2,"カンマ,含み"
3,てすと3,"ダブルクォーテーション""含み"
出力結果例
1 : 改行
含み
2 : カンマ,含み
3 : ダブルクォーテーション"含み

サンプルのソースは http://github.com/fits/try_samples/tree/master/blog/20101129/

Ruby の場合

Ruby では標準添付されている CSV ライブラリを使います。

parse_csv.rb
require "csv"

CSV.foreach(ARGV[0]) do |r|
    puts "#{r[0]} : #{r[2]}"
end

以下の環境で実行してみました。

実行例
> ruby parse_csv.rb test.csv
> jruby parse_csv.rb test.csv

Groovy の場合

Groovy や後述の Scala には今回のケースのような CSV ファイルを簡単にパースできるライブラリが標準で用意されていないため、opencsv を使う事にします。

parse_csv.groovy
import java.io.FileReader
import au.com.bytecode.opencsv.CSVReader

def reader = new CSVReader(new FileReader(args[0]))

while((r = reader.readNext()) != null) {
    println "${r[0]} : ${r[2]}"
}

以下の環境で実行してみました。

  • Groovy 1.7.5
  • opencsv 2.2
実行例
> set CLASSPATH=opencsv-2.2.jar
> groovy parse_csv.groovy test.csv

Scala の場合

Scala でも opencsv を使いました。

ただし、Scala では while((r = reader.readNext()) != null) のように書けないので、代わりに Iterator.continually(reader.readNext).takeWhile(_ != null) を使います。

parse_csv.scala
import java.io.FileReader
import au.com.bytecode.opencsv.CSVReader

val reader = new CSVReader(new FileReader(args(0)))

Iterator.continually(reader.readNext).takeWhile(_ != null).foreach {r =>
    println(r(0) + " : " + r(2))
}

また、以下のようにList化してパターンマッチを使う方法もありかと思います。

parse_csv2.scala
import java.io.FileReader
import au.com.bytecode.opencsv.CSVReader

val reader = new CSVReader(new FileReader(args(0)))

Iterator.continually(reader.readNext).takeWhile(_ != null).map(_.toList).foreach {
    case no :: title :: content :: _ => println(no + " : " + content)
    case _ =>
}

以下の環境で実行してみました。

  • Scala 2.8.1
  • opencsv 2.2
実行例
> scala -cp opencsv-2.2.jar parse_csv.scala test.csv

opencsv のビルド方法

http://sourceforge.net/projects/opencsv/ から opencsv-2.2-src-with-libs.tar.gz ファイルをダウンロードし、適当なディレクトリに展開後、Ant でビルドすれば、deploy/opencsv-2.2.jar ファイルが作成されます。

ビルド例
> cd opencsv-2.2
> ant
・・・
BUILD SUCCESSFUL