CSVパーサ by Scala

Scalaのパーサコンビネータを使ってみました。いくつかパーサがありますから、対象データや実行したい処理に応じて、どれが適しているかを考えながら使う必要があります。

要点だけ。RegexParsersを使うと正規表現でいろいろと表現ができるので便利です。終端記号などを手っ取り早く表現するのに使えそうです。行末はcrlfで定義しています。各行は値vをカンマ「,」で区切っていると定義しています。値には英数字しか許していません。RegexParsersでは、skipWhitespaceをfalseにしないと空白(0x30,改行コード,タブコードなど)を読み飛ばしてしまいます。これにきづかずはまりました…

package org.sssg.soft.scala.sample.combinator.parsing.csv
import scala.util.parsing.combinator.RegexParsers
import java.io.FileReader

// 単純な方法
class CsvParsers extends RegexParsers {
  def values : Parser[Any] = rep(line <~ crlf)
  def crlf : Parser[Any] = """(\r\n|\n|\r)""".r
  def line : Parser[Any] = v~rep(","~>v)
  def v : Parser[Any] = """[0-9a-zA-Z]*""".r
  override val skipWhitespace = false
}

object CsvParsersRunner {
  def main(args: Array[String]) {
    val parser = new CsvParsers();
    val reader = new FileReader("sample.csv")
    println(parser.parseAll(parser.values, reader))
  }
}

このバージョンは簡易版なので、「,」でしか区切りを判断していないので、RFC4180で定義されているようなCSVデータを正しく区切ることはできません。これぐらいだと、JavaのStringTokenizerと同レベルなので、ありがたみはあまり感じないかもしれません。ただ、解析器のプログラムの見通しがすごく良いというのに注目すると、パーサコンビネータの強力さが何となくわかるはずです。

同じタグの記事: Scala
同じカテゴリの記事: Program
関連書籍: Scala