使用scala-parser-combinators,我想尝试使用postfix字符串(end
)进行解析。但以前的解析器cought end
内容。怎么解决?
(只是改变"[^z]".r
并不是一个好的答案。)
val input = "aaabbbzzz"
parseAll(body, input) // java.lang.IllegalStateException: `zzz' expected but end of source found
def body: Parser[List[String]] = content.+ <~ end
def content: Parser[String] = repChar // more complex like (repChar | foo | bar)
def repChar: Parser[String] = ".{3}".r // If change this like "[^z]{3}", but no flexibility.
def end: Parser[String] = "zzz"
我想尝试以下内容。
"""(.*)(?=zzz)""".r.into(str => ...check content.+ or not... <~ end)
end
字符串。答案 0 :(得分:0)
解决此问题的另一种方法是使用not
组合子。您只需要检查您正在解析的内容不是end
值。
诀窍是not
不消耗输入,所以如果not(end)
成功(意味着end
失败)那么我们没有达到停止条件所以我们可以解析使用content
解析器的三个字符使end
解析器失败。
与注释中链接的非贪婪方法一样,对于输入中包含“zzz”之后的字符的输入(例如"aaabbbzzzzzz"
),它将失败。
但是对于您的用例可能就足够了。所以你可以尝试一下 用:
def body: Parser[List[String]] = rep(not(end) ~> content) <~ end
实际上这是一种takeUntil
解析器,因为它会反复解析content
,直到您能够使用end
进行解析。