如何测试Scala组合器解析器是否与字符串匹配

时间:2012-12-13 05:00:39

标签: scala parser-combinators

我有一个Scala组合子解析器,可以处理以逗号分隔的十进制数列表。

object NumberListParser extends RegexParsers {
  def number: Parser[Double] = """\d+(\.\d*)?""".r ^^ (_.toDouble)

  def numbers: Parser[List[Double]] = rep1sep(number, ",")

  def itMatches(s: String): Boolean = parseAll(numbers, s) match {
    case _: Success[_] => true
    case _ => false
  }
}

当给定与模式匹配的字符串时,itMatches函数返回true。例如:

NumberListParser.itMatches("12.4,3.141") // returns true
NumberListParser.itMatches("bogus") // returns false

有更简洁的方法吗?我在文档中找不到一个,但是我的函数看起来有点冗长,所以我想知道我是否忽略了一些东西。

3 个答案:

答案 0 :(得分:3)

我想我应该将我的评论添加为答案,因为这是答案。您可以在ParseResult上使用successful方法,该方法专为此目的而设计:

import scala.util.parsing.combinator._

object NumberListParser extends RegexParsers {
  def number = """\d+(\.\d*)?""".r ^^ (_.toDouble)
  def numbers = rep1sep(number, ",")

  def itMatches(s: String): Boolean = parseAll(numbers, s).successful
}

这提供了与您的实现完全相同的行为。

答案 1 :(得分:2)

您可以使用JavaTokenParsers并从decimalNumbers

中受益
object NumberListParser extends JavaTokenParsers {
  def number: Parser[Double] = decimalNumbers ^^ (_.toDouble)
  def numbers: Parser[List[Double]] = rep1sep(number, ",")
  def itMatches(s: String): Boolean = parseAll(numbers, s) match {
    case _: Success[_] => true
    case _ => false
  }
}

答案 2 :(得分:1)

您可以将itMatches定义为:

def itMatches(s: String): Boolean = parseAll(numbers, s).map{ r => true }.getOrElse(false)

您不需要解析器。 Regex就够了:

var R = """\d+(\.\d*)?(,\d+(\.\d*)?)*""".r
def itMatches(s: String) = s match {
  case R(_*) => true
  case _ => false
}

scala> itMatches("12.4,3.141")
res0: Boolean = true

scala> itMatches("bogus")
res1: Boolean = false