贪心匹配除非遇到特定的字符串,然后匹配到特定的组?

Greedy match unless it runs into specific string, then match to specific group?

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

这是我坚持的部分:

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

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

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

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

预计input/output:

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

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

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

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

说明

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

Regex demo

如果您使用正向预测,它永远不会匹配第二条消息。所以使用交替

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