首先,代码:
package com.digitaldoodles.markup
import scala.util.parsing.combinator.{Parsers, RegexParsers}
import com.digitaldoodles.rex._
class MarkupParser extends RegexParsers {
val stopTokens = (Lit("{{") | "}}" | ";;" | ",,").lookahead
val name: Parser[String] = """[@#!$]?[a-zA-Z][a-zA-Z0-9]*""".r
val content: Parser[String] = (patterns.CharAny ** 0 & stopTokens).regex
val function: Parser[Any] = name ~ repsep(content, "::") <~ ";;"
val block1: Parser[Any] = "{{" ~> function
val block2: Parser[Any] = "{{" ~> function <~ "}}"
val lst: Parser[Any] = repsep("[a-z]", ",")
}
object ParseExpr extends MarkupParser {
def main(args: Array[String]) {
println("Content regex is ", (patterns.CharAny ** 0 & stopTokens).regex)
println(parseAll(block1, "{{@name 3:4:foo;;"))
println(parseAll(block2, "{{@name 3:4:foo;; stuff}}"))
println(parseAll(lst, "a,b,c"))
}
}
然后,运行结果:
[info] == run ==
[info] Running com.digitaldoodles.markup.ParseExpr
(Content regex is ,(?:[\s\S]{0,})(?=(?:(?:\{\{|\}\})|;;)|\,\,))
[1.18] parsed: (@name~List(3:4:foo))
[1.24] failure: `;;' expected but `}' found
{{@name 3:4:foo;; stuff}}
^
[1.1] failure: string matching regex `\z' expected but `a' found
a,b,c
^
我使用自定义库来组合我的一些正则表达式,所以我打印出了“内容”正则表达式;它应该基本上是任何文本,但不包括某些令牌模式,使用积极的先行断言强制执行。
最后,问题:
1)第一次运行“block1”成功,但不应该,因为“repsep”函数中的分隔符是“::”,而“:”被解析为分隔符。
2)“block2”上的运行失败,大概是因为前瞻条款不起作用 - 但我无法弄清楚为什么会这样。前瞻性条款已经在“block1”上运行的“repsep”中运行,并且似乎在那里工作,那么为什么它应该在第2块失败?
3)对“lst”的简单repsep练习失败,因为在内部,解析器引擎似乎正在寻找边界 - 这是我需要以某种方式解决的问题吗?
谢谢, 肯
答案 0 :(得分:2)
1)不,“::”不被解析为分隔符。如果是,则输出为(@name~List(3, 4, foo))
。
2)之所以发生这种情况是因为“}}
”也是一个分隔符,所以它需要最长的匹配 - 包含“;;
”的那个。如果您使前面的表达式非渴望,那么它将在“s
”上的“stuff
”处失败,我认为这是您所期望的。
3)你传了一个文字而不是正则表达式。将"[a-z]"
修改为"[a-z]".r
即可。