我正在尝试捕获日志中的IP地址,如果地址为0.0.0.0,则还原主机名。
以下是日志的一些示例:
Foo bar ip=0.0.0.0 baz host=YOLO-PC foobar bazinga
在这种情况下,我想要“YOLO-PC”,因为IP是0.0.0.0
Foo bar ip=12.23.34.45 baz host=FOOBAR-PC foobar bazinga
在这种情况下,我想要12.23.34.45
。
这是我试过的:
ip=(?:0\.0\.0\.0|(\d+\.\d+\.\d+\.\d+)).*?host=(?(1).|(\S+))
它有效,但是当IP为0.0.0.0时,它会创建第二个组,其后面的程序无法获取组#2,只能获取组#1。
我该怎么做?把它全部放在一个组中?有更好的解决方案吗?
答案 0 :(得分:3)
从您的问题中不清楚您正在处理哪种环境/语言/正则表达式。但PCRE正则表达式实际上允许您使用(?|some(capture)|another(capture))
语法执行此操作:
ip=(?|0\.0\.0\.0.*?host=(\S+)|(\d+\.\d+\.\d+\.\d+))
您可以在debuggex visualisation中看到两个组的编号均为 1 。在regex101上,您可以看到右侧的捕获。
或者(如果你不使用PCRE),我想你可以这样做。它不那么严格,但适用于大多数引擎。您当前的正则表达式对IP格式并不特别严格(允许高于255的数字等),所以这对您来说可能不是问题。
ip=(?:0\.0\.0\.0.*?host=)?(\S+)
答案 1 :(得分:1)
结果中的组数等于正则表达式中( )
组的数量。你引用它们的顺序是开头的parens出现在正则表达式中的顺序。有些组可能不匹配并且为空。
因此,在您的情况下,您将始终拥有两个小组。组1是非零ip,组2是主机名。如果IP为0.0.0.0,则组1将为空。如果没有,则第2组将为空。
您是否只能检查代码中哪个组为空并使用另一个组?
答案 2 :(得分:0)
使用从左到右尝试的替换:
(?<=ip)(?!0.0.0.0)\S+|(?<=host=)\S+
请参阅demo
由于使用环顾四周,这仅匹配您的目标输入。如果它全部为零,那么前面的负面看法决定不使用ip。
只选择第一个匹配。