【问题标题】:String ending with character in parboiled2, when the string can contain that character以 parboiled2 中的字符结尾的字符串,当字符串可以包含该字符时
【发布时间】: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 }

最终,端点的可匹配字符串由空格或行尾终止,因此一种选择是只捕获空格,然后单独解析字符串,但我希望在主解析器。

【问题讨论】:

  • 你能举一个有效的“更长的字符串”的例子,以及你希望从那个字符串中得到什么(即:成功的匹配)吗?
  • @David 我添加了一些上下文,同时试图保持问题相对孤立。实际情况要复杂得多(codespec),但希望有什么足以理解这个问题。
  • 所以你可以有一行bind 1:::80,你想输出Bind(Endpoint(Some("1::"), Some(80)), Seq())?这是您出现问题的好案例吗?
  • 是的,这是具体问题的一个很好的例子。

标签: scala peg parboiled parboiled2


【解决方案1】:

我认为以下内容应该适用于您的问题描述:

def noColons = rule { zeroOrMore(noneOf(":")) }
def colonWithNext = rule { ':' ~ &(noColons ~ ':') }
def address = rule { capture(oneOrMore(noColons).separatedBy(colonWithNext)) ~ ':' }

您的代码的问题在于使用了 ~ 组合器,因为像 A ~ B 这样的表达式仅在首先 A 匹配然后 B 匹配时才匹配,但如果规则 B 属于 规则 A。这里不涉及回溯,parboiled2 解析器只回溯替代方案。

因此,在这种情况下,您必须确保仅在后面有另一个 ':' 时才使用它。

【讨论】:

  • 太好了,谢谢——我开始在这些方面有所了解,但 captureseparatedBy 的组合起到了作用(我丢弃了分隔符)。此外,我试图将它写在一个规则中,而将其拆分会使事情变得更清晰。
猜你喜欢
  • 1970-01-01
  • 2018-10-16
  • 1970-01-01
  • 2011-06-06
  • 1970-01-01
  • 1970-01-01
  • 2011-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多