卡在正则表达式问题上。我正在尝试提取AD FS日志中某个字段(“客户端IP:”)之后的所有ip。
我的日志如下所示(为了节省空间而被截断):
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。
有什么想法吗?
答案 0 :(得分:1)
您可以通过添加基于\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)
将411
或512
捕获到组1中,然后\R
匹配一个换行符,并且{ {1}}尽可能匹配任意数量的0+字符,直到匹配到另一个换行符为止,随后的子模式将紧随其后).*?\R
-匹配重置操作符会丢弃所有匹配的文本,直到整个匹配缓冲区为止。您还有一个小问题:\K
应该写为[\d\%A-Fa-z\.]
。