5

是否可以使用 Scala 解析器组合器反转匹配?我正在尝试使用以一组关键字开头的解析器匹配行。我可以使用烦人的零宽度负前瞻正则表达式(例如"(?!h1|h2).*")来做到这一点,但我宁愿使用 Scala 解析器来做到这一点。我能想到的最好的是:

def keyword = "h1." | "h2."
def alwaysfails = "(?=a)b".r
def linenotstartingwithkeyword = keyword ~! alwaysfails | ".*".r

这个想法是我用的~!禁止回溯到所有匹配的正则表达式,然后继续使用不匹配的正则表达式 "(?=a)b".r。(顺便说一句,是否有一个总是失败的预定义解析器?)这样,如果找到关键字,则不会匹配该行,但如果关键字不匹配,则会匹配该行。

我想知道是否有更好的方法来做到这一点。有没有?

4

1 回答 1

7

你可以not在这里使用:

import scala.util.parsing.combinator._

object MyParser extends RegexParsers {
  val keyword = "h1." | "h2."
  val lineNotStartingWithKeyword = not(keyword) ~> ".*".r

  def apply(s: String) = parseAll(lineNotStartingWithKeyword, s)
}

现在:

scala> MyParser("h1. test")
res0: MyParser.ParseResult[String] = 
[1.1] failure: Expected failure

h1. test
^

scala> MyParser("h1 test")
res1: MyParser.ParseResult[String] = [1.8] parsed: h1 test

请注意,还有一个failure方法 on Parsers,因此您也可以使用keyword ~! failure("keyword!"). 但not无论如何,要好得多。

于 2012-10-31T22:08:14.043 回答