【问题标题】:Greedy match unless it runs into specific string, then match to specific group?贪婪匹配,除非它遇到特定的字符串,然后匹配到特定的组?
【发布时间】:2019-11-26 15:11:33
【问题描述】:

我正在尝试使用 regex/grok 解析 logstash 中的 URL。我已经弄清楚了大部分字符串,但我被困在最后一部分,我发现很难解释:

这是我坚持的部分:

在 Logstash 中,我想捕获整个字符串并将其转储到名为 api_info 的字段中,除非它包含字符串 &freeText=,在这种情况下,我希望 &freeText= 之前的所有内容都进入 @ 987654324@ 字段,&freeText= 之后的所有内容都进入 api_search 字段。否则,api_search 字段应为空。

这是我到目前为止/尝试过的:

(?<api_info>.*?)(?=&freeText=)?(:?&freeText=)(?<api_search>.*)?
(?<api_info>.*)((:?&freeText=)(?<api_search>.*))?

输入字符串: womens%7cshoes%ctrainer&amp;pageSize=60&amp;freeText=shoes30

预期输入/输出:

womens%7cshoes%ctrainer&pageSize=60&freeText=shoes30
api_info:"womens%7cshoes%ctrainer&pageSize=60", api_search:"shoes30"
mens%7trainers&pageSize=90
api_info:"mens%7trainers&pageSize=90", api_search:null

【问题讨论】:

  • 为什么不简单地用&amp;freeText分割字符串并根据分割值决定api_search

标签: regex pcre regex-lookarounds logstash-grok regex-greedy


【解决方案1】:

请注意确定空组是否转换为 null,但您可以使用交替匹配字符串结尾 $&amp;freeText=

对于 api_search 组,您可以匹配任何字符 0+ 次。

(?<api_info>.+?)(?:&freeText=|$)(?<api_search>.*)

说明

  • (?&lt;api_info&gt;.+?)api_info,匹配除换行符以外的任何字符 1 次以上
  • (?:&amp;freeText=|$) 匹配 &amp;freeText= 或断言字符串结尾
  • (?&lt;api_search&gt;.*)api_search,匹配除换行符以外的任何字符 0+ 次

Regex demo

【讨论】:

    【解决方案2】:

    如果您使用积极的前瞻,它永远不会匹配第二条消息。所以使用交替

    "((?<api_info>.*)(&freeText=)(?<api_search>.*)?|(?<api_info>.*))"
    

    【讨论】:

      猜你喜欢
      • 2013-06-09
      • 2017-10-16
      • 1970-01-01
      • 1970-01-01
      • 2015-02-11
      • 2020-04-04
      • 1970-01-01
      • 1970-01-01
      • 2019-08-01
      相关资源
      最近更新 更多