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

时间:2018-10-02 19:51:15

标签: regex pcre

卡在正则表达式问题上。我正在尝试提取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。

有什么想法吗?

1 个答案:

答案 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)411512捕获到组1中,然后\R匹配一个换行符,并且{ {1}}尽可能匹配任意数量的0+字符,直到匹配到另一个换行符为止,随后的子模式将紧随其后)
  • .*?\R-匹配重置操作符会丢弃所有匹配的文本,直到整个匹配缓冲区为止。

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