【发布时间】:2015-01-27 13:24:28
【问题描述】:
我在编写 parboiled2 解析器时遇到了一个棘手的问题,即我需要匹配行的一部分,该行是一个以: 字符标记其结尾的字符串。这很容易,除了字符串可以包含 : 字符。
目前我有这个将字符串视为一组以冒号结尾的字符串并将它们连接起来,但这会消耗我不想要的尾随 :,因为尾随 : 不是一部分字符串本身。
def address = rule { capture(oneOrMore(zeroOrMore(noneOf(":")) ~ ":")) }
我觉得我应该在这里的某个地方使用&(":"),但我在匹配插页式: 字符时很难做到这一点。
成功匹配示例(作为较长字符串的一部分):
-
localhost:->localhost -
1:::->1:: -
:::->::
不匹配:
:
欢迎任何建议,即使是“你不能这样做”,这样我就可以停止绞尽脑汁了。
上下文是解析 HAProxy 配置文件中的 bind 设置。给定以下(简化的)案例类的一些有效字符串示例是:
case class Bind(endpoint: Endpoint, params: Seq[String])
case class Endpoint(address: Option[String], port: Option[Int])
-
bind :80->Bind(Endpoint(None, Some(80)), Seq()) -
bind localhost:80->Bind(Endpoint(Some("localhost"), Some(80)), Seq()) -
bind localhost->Bind(Endpoint(Some("localhost"), None), Seq()) -
bind :80 param1->Bind(Endpoint(None, Some(80)), Seq("param1")))
换句话说,如果有一个字符串,它需要在最终的: 之前终止,因为这表明存在端口。 endpoint 规则如下所示:
def endpoint = rule { optional(address) ~ optional(':' ~ int) ~> Endpoint }
最终,端点的可匹配字符串由空格或行尾终止,因此一种选择是只捕获空格,然后单独解析字符串,但我希望在主解析器。
【问题讨论】:
-
你能举一个有效的“更长的字符串”的例子,以及你希望从那个字符串中得到什么(即:成功的匹配)吗?
-
所以你可以有一行
bind 1:::80,你想输出Bind(Endpoint(Some("1::"), Some(80)), Seq())?这是您出现问题的好案例吗? -
是的,这是具体问题的一个很好的例子。
标签: scala peg parboiled parboiled2