Skip to content

Instantly share code, notes, and snippets.

@wipiano
Last active May 10, 2017 10:49
Show Gist options
  • Save wipiano/702847e465e006647ac784ffb2696d6b to your computer and use it in GitHub Desktop.
Save wipiano/702847e465e006647ac784ffb2696d6b to your computer and use it in GitHub Desktop.
Scala のパーサコンビネータ (RegexParsers) を使った郵便番号のパーサ
name := "PostalCodeParser"
version := "1.0"
scalaVersion := "2.12.2"
// Parser Combinator は外部ライブラリになりました
libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.6"
import scala.util.parsing.combinator._
// パーサ
class PostalCodeParser extends RegexParsers {
// 地域番号 ( "-" より前の 3 桁)
def regionCode: Parser[Int] = """[0-9]{3}""".r ^^ { _.toInt }
// "-" よりあとの 4 けた
def detailCode: Parser[Int] = """[0-9]{4}""".r ^^ { _.toInt }
// 区切り ("-")
def separator: Parser[String] = """-""".r ^^ { _.toString }
// 郵便番号
def postalCode: Parser[PostalCode] = regionCode ~ separator ~ detailCode ^^ { case r ~ s ~ d => PostalCode(r, d) }
}
// 郵便番号をあらわす case class
case class PostalCode(region: Int, detail: Int) {
override def toString = s"${"%03d".format(region)}-${"%04d".format(detail)}"
}
// テスト用に 123-4567 をパースします
object TestPostalCodeParser extends PostalCodeParser {
def main(args: Array[String]) = {
parse(postalCode, "123-4567") match {
case Success(matched, _) => println(matched.toString)
case Failure(msg, _) => println("FAILURE: " + msg)
case Error(msg, _) => println("ERROR: " + msg)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment