Ruby, Groovy, Scala での Excel準拠 CSV ファイルのパース処理 - opencsv使用、Iterator.continually() 等
Excel の仕様に準拠した以下のような CSV ファイル(改行・カンマ・ダブルクォーテーションを要素内に含む)をパースし、第1・3の要素を標準出力に出力するサンプルを Ruby、Groovy、Scala で作成してみました。
出力結果例
1 : 改行 含み 2 : カンマ,含み 3 : ダブルクォーテーション"含み
サンプルのソースは http://github.com/fits/try_samples/tree/master/blog/20101129/
Ruby の場合
Ruby では標準添付されている CSV ライブラリを使います。
実行例
> 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 では 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