如何使用scala组合器匹配句子中的所有单词?

时间:2014-11-24 14:54:37

标签: scala parser-combinators

对于使用scala组合器进行的第一次测试,我试图从句子中获取所有单词,但我只是得到了#34;没有"来自以下代码:

import java.io.File
import scala.io.Source
import scala.util.parsing.combinator._

object PgnReader extends TagParser {

  def parseFile(inputFile:File) = {
    val pgnStream = Source.fromFile(inputFile)
    val pgnStr = pgnStream.mkString
    println(parseAll(tag, "Hello World !").getOrElse("None"))
    pgnStream.close
  }
}

trait TagParser extends RegexParsers {
  val tag:Parser[String] = """[:alpha:]+""".r ^^ (_.toString)
}

我想得到类似的东西:

Hello
World

甚至喜欢:

List(Hello, World)

我的代码是否正确?

我正在使用scala 2.11和scala combinators

2 个答案:

答案 0 :(得分:4)

您应该使用类似的东西来匹配令牌序列而不是一个令牌:

trait TagParser extends RegexParsers {
  val tags: Parser[List[String]] = rep("""[a-zA-Z]+""".r)
}

rep是:

  

用于重复的解析器生成器。

     

rep(p)重复使用p来解析输入,直到p失败(结果   是p)的连续结果列表。

http://www.scala-lang.org/files/archive/nightly/docs/parser-combinators/index.html#scala.util.parsing.combinator.RegexParsers

答案 1 :(得分:1)

我认为这可能会让你更接近:

trait TagParser extends RegexParsers {
  val tag = rep("""\p{Alpha}+""".r) ^^ (_.map(_.toString))
}

在Scala (as inherited from Java)中,POSIX字符类具有不同的语法。 rep()语法允许多次出现(给出List())。

那仍然会在惊叹号上窒息,所以你可以稍微增加你的正则表达式。我可能也会采用" tag"的概念。和"标签"分开使事情更清楚:

trait TagParser extends RegexParsers {
  val tags = rep(tag)
  val tag = """\p{Alpha}+|!""".r ^^ (_.toString)
}
...
println(parseAll(tags, "Hello World !").getOrElse(None))
...