2012-10-31 33 views
5

是否可以反转与Scala语法分析器组合器的匹配?我试图用一系列关键字开头的解析器匹配而不是。我可以用恼人的零宽度负向预测正则表达式(例如"(?!h1|h2).*")来做到这一点,但我宁愿使用Scala解析器来做到这一点。我已经能够拿出最好的是这样的:斯卡拉分析器 - 组合器:如何颠倒比赛?

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

的想法是在这里,我用的〜!禁止回溯到全匹配的正则表达式,然后继续使用正则表达式“(?= a)b”.r,它不匹配任何内容。 (顺便说一下,是否有预定义的解析器总是失败?)这样,如果找到关键字,则不会匹配该行,但如果关键字不匹配,则会匹配该行。

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

回答

6

你可以在这里使用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 

注意,也有上Parsers一个failure方法,所以你也可以同样有keyword ~! failure("keyword!")写您的版本。但是not好多了,无论如何。