AD FS通过Regex记录多个ip提取

AD FS log multiple ip extraction through Regex

卡在 pcre 正则表达式问题上。我正在尝试提取 AD FS 日志中某个字段 ("Client IP: ") 之后的所有 ips。
我的日志看起来像这样(截断以保存 space):

EventCode=411
EventType=0
Type=Information
SidType=1
TaskCategory=Printers
OpCode=Info
Token Type: 
http://schemas.microsoft.com/ws/2006/05/identitymodel/tokens/UserName  

Client IP: 
110.19.100.155,2603:1032:205:14::5 

Error message: 
******-This user can't sign in because this account is currently disabled 

所以最终的结果是我在字段 src_ip 下获得了两个 IP 地址,并且它只在找到 EventCode=411 或 512 等时才尝试正则表达式...

我目前的情况是这样的:

(\s\n|,)(?<src_ip>(?:(?:\d{1,3}\.){3}(?:\d{1,3}))|(?:(?:::)?(?:[\dA-Fa-f]{1,4}:{1,2}){1,7}(?:[\d\%A-Fa-z\.]+)?(?:::)?)|(?:::[\dA-Fa-f\.]{1,15})|(?:::))

这有效,但不区分仅具有所需事件代码的事件。所以当我这样做时:

(?ms)(?:EventCode=(411|512))\n.*?(\s\n|,)(?P<src_ip>(?:(?:\d{1,3}\.){3}(?:\d{1,3}))|(?:(?:::)?(?:[\dA-Fa-f]{1,4}:{1,2}){1,7}(?:[\d\%A-Fa-z\.]+)?(?:::)?)|(?:::[\dA-Fa-f\.]{1,15})|(?:::))

只取第一个ip

有什么想法吗?

您可以通过添加基于 \G 运算符的自定义边界来稍微修改您的模式,该边界匹配字符串的开头,或者您需要的是上一个成功匹配的结尾:

(?ms)(?:\G(?!\A)\s*,\s*|EventCode=(411|512)\n.*?\R)\K(?P<src_ip>(?:\d{1,3}\.){3}(?:\d{1,3})|(?:::)?(?:[\dA-Fa-f]{1,4}:{1,2}){1,7}[\d%A-Fa-f.]*(?:::)?|::[\dA-Fa-f.]{1,15}|::)

参见regex demo

基本上,主要区别是(?:\G(?!\A)\s*,\s*|EventCode=(411|512)\n.*?\R)\K:

  • \G(?!\A)\s*,\s* - 前面成功匹配的结尾(字符串位置的开始已经用负先行 (?!\A) 减去),然后是一个用 0+ 个空格括起来的逗号
  • | - 或
  • EventCode=(411|512)\n.*?\R - EventCode= 子字符串,然后 (411|512)411512 捕获到第 1 组,然后 \R 匹配换行符并且 .*?\R 匹配任意数量的 0+ 个字符,尽可能少直到另一个换行符,随后的子模式将被跟随)
  • \K - 匹配重置运算符丢弃整个匹配缓冲区中到目前为止匹配的所有文本。

您还有一个小问题:[\d\%A-Fa-z\.] 应该写成 [\d\%A-Fa-f.]