首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >字符串以parboiled2中的字符结尾,当字符串可以包含该字符时

字符串以parboiled2中的字符结尾,当字符串可以包含该字符时
EN

Stack Overflow用户
提问于 2015-01-27 13:24:28
回答 1查看 411关注 0票数 1

我在编写parboiled2解析器时遇到了一个棘手的问题,那就是我需要匹配一行的一部分,这是一个字符串,它的结尾有一个:字符标记。这很容易,只是字符串可以包含:字符。

目前,我已经得到了这样的消息,它将字符串视为一组以冒号结尾的字符串,并将它们连接起来,但这会消耗我不想要的尾随:,因为尾随:本身并不是字符串的一部分。

代码语言:javascript
复制
def address = rule { capture(oneOrMore(zeroOrMore(noneOf(":")) ~ ":")) }

我觉得我应该在这里的某个地方使用&(":"),但是在匹配中间:字符时,我很难做到这一点。

成功匹配示例(作为较长字符串的一部分):

  • localhost: -> localhost
  • 1::: -> 1::
  • ::: -> ::

不匹配:

  • :

任何建议都是受欢迎的,即使是“你不能这么做”,这样我就可以停止绞尽脑汁了。

其上下文是在一个bind配置文件中解析HAProxy设置。给定以下(简化)案例类的有效字符串的一些示例如下:

代码语言:javascript
复制
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规则如下所示:

代码语言:javascript
复制
def endpoint = rule { optional(address) ~ optional(':' ~ int) ~> Endpoint }

最终,端点的可匹配字符串被空格或行尾终止,因此有一种选择是捕捉到空间,然后单独解析字符串,但我希望在主解析器中这样做。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-28 07:18:29

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

代码语言:javascript
复制
def noColons = rule { zeroOrMore(noneOf(":")) }
def colonWithNext = rule { ':' ~ &(noColons ~ ':') }
def address = rule { capture(oneOrMore(noColons).separatedBy(colonWithNext)) ~ ':' }

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

因此,在这种情况下,您必须确保消费':‘只有当有另一个跟随它。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28171606

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档