对于使用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
答案 0 :(得分:4)
您应该使用类似的东西来匹配令牌序列而不是一个令牌:
trait TagParser extends RegexParsers {
val tags: Parser[List[String]] = rep("""[a-zA-Z]+""".r)
}
rep
是:
用于重复的解析器生成器。
rep(p)重复使用p来解析输入,直到p失败(结果 是p)的连续结果列表。
答案 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))
...