如何在自定义Grok模式中引用正则表达式组?

6

我希望在日志行中添加特定URI参数的字段

以下是一个示例日志行:

2017-03-12 21:34:36 W3SVC1 webserver 1.1.1.1 GET /webpage.html param1=11111&param2=22222&param3=&param4=4444444 80 - 2.2.2.2 HTTP/1.1 Java/1.8.0_121 - - balh.com 200 0 0 311 244 247 - -

我希望增加param1,param2,param3和param4字段。

我正在使用以下grok过滤器:

  grok {
    match => [ "message", "(?<param1>param1=(.*?)&)"]
  }

所以这个正则表达式使用捕获组来获取在“param1=”和“&”之间的文本。但是grok忽略了捕获组,得到了“param1=11111&”。我只想捕获“111111”。
我该如何使用捕获组1或告诉grok使用我的正则表达式捕获组?
编辑 这个几乎可以工作:
  grok {
    match => [ "message", "(?<param1>param1=(?<param1>.*?)&)"]
  }

我猜我在这里使用了两个同名的命名组。问题在于“param1”字段对于每个组都有两个条目。“param1=11111&”和“11111”各有一个。我怎样才能只获取第二个组呢?

2个回答

8
默认情况下,grok仅考虑命名捕获组,编号捕获组不会触发字段创建。如果您想覆盖此行为,请将named_captures_only设置为false
``` named_captures_only - 值类型为boolean - 默认值为true - 如果为true,则仅存储来自grok的命名捕获。 ```
然而,使用命名捕获组没有问题(我会使用否定字符类[^&]*代替具有消耗性&的懒惰匹配点):
\bparam1=(?<param1>[^&]*)

[^&]* 匹配除了 & 之外的 0 或多个字符,因此也会匹配空参数(您可以通过将 * 更改为 + 或使用 keep_empty_captures 参数来控制),并在字符串末尾。

enter image description here


这样做比我现在的方式更快或资源消耗更少吗? - red888
1
一个带有贪婪量词的否定字符类匹配速度比懒惰量化的点要快得多。我不认为在实践中性能上有很大的差异,因为输入不是非常长的字符串,然而,最好的做法是针对每种情况使用适当的工具(这里是模式),在正则表达式中,这意味着当您需要匹配来自定义范围/集合或其他未定义字符时,您需要使用否定字符类。 - Wiktor Stribiżew

1
这个可以工作:

  grok {
    match => [ "message", "(?:param1=(?<param1>.*?)&)"]
  }

所以我猜我在这里使用了一个非捕获组,其中包含一个命名捕获组。因此,父组的匹配被丢弃,嵌套的命名匹配是唯一返回的内容。

这样做是我想要的吗?还是这样做是错误的,只是碰巧它做到了我想要的?


1
只是提供信息:(?:...),一个非捕获组,在这里没有任何作用,如果你将其删除,模式将以相同的方式工作。当非捕获组包含交替项或者需要匹配n到m次出现、一次/零次或一次或零次出现时,才需要使用非捕获组。 - Wiktor Stribiżew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接