2012-10-31 9 views
5

Scalaパーサーコンビネータとの一致を反転することはできますか?私はではないパーサーと行を一致させようとしています。は一連のキーワードで始まります。私は迷惑なゼロ幅の先読み正規表現(例えば"(?!h1|h2).*")でこれを行うことができますが、私はむしろScalaパーサでそれをやります。私が思い付くことができました最高のはこれです:Scala parser-combinators:一致を逆転する方法は?

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

アイデアは、私が使用することをここにある〜!すべて一致するregexpへのバックトラッキングを禁止し、何も一致しない正規表現 "(?= 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) 
} 

:あなただけのようにもkeyword ~! failure("keyword!")であなたのバージョンを書かれていることができるように、またParsersfailure方法があることを

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 

注意。しかし、とにかく、notはもっとよかったです。

関連する問題