如何避免在正则表达式中使用不同的捕获组号?
How to avoid different capture group numbers in a regex?
我正在尝试在日志中捕获 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。
我该怎么做?全部放在一个组里?有更好的解决方案吗?
结果中的组数等于正则表达式中的 ( )
组数。您引用它们的顺序是左括号在正则表达式中出现的顺序。某些组可能不匹配且为空。
所以在你的情况下,你总是有两个组。第 1 组是非零 ip,第 2 组是主机名。如果 IP 为 0.0.0.0,则组 1 将为空。如果不是,则第 2 组将为空。
你不能只检查你的代码哪一组是空的,然后使用另一组吗?
从你的问题中不清楚你正在处理哪种 environment/language/regex 口味。但是 PCRE 正则表达式实际上让你用 (?|some(capture)|another(capture))
语法来做到这一点:
ip=(?|0\.0\.0\.0.*?host=(\S+)|(\d+\.\d+\.\d+\.\d+))
您可以从 debuggex visualisation that both groups are numbered 1. And on regex101 中看到右侧的捕获。
或者(如果您不使用 PCRE),我想您可以这样做。它不那么严格,但适用于大多数引擎。您当前的正则表达式对 IP 格式不是特别严格(允许大于 255 的数字等),所以这对您来说可能不是问题。
ip=(?:0\.0\.0\.0.*?host=)?(\S+)
使用交替,尝试从左到右:
(?<=ip)(?!0.0.0.0)\S+|(?<=host=)\S+
见demo
由于使用环顾四周,这仅匹配您的目标输入。消极的展望决定不使用 ip 如果它全部为零。
只选择 第一个 匹配项。
我正在尝试在日志中捕获 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。
我该怎么做?全部放在一个组里?有更好的解决方案吗?
结果中的组数等于正则表达式中的 ( )
组数。您引用它们的顺序是左括号在正则表达式中出现的顺序。某些组可能不匹配且为空。
所以在你的情况下,你总是有两个组。第 1 组是非零 ip,第 2 组是主机名。如果 IP 为 0.0.0.0,则组 1 将为空。如果不是,则第 2 组将为空。
你不能只检查你的代码哪一组是空的,然后使用另一组吗?
从你的问题中不清楚你正在处理哪种 environment/language/regex 口味。但是 PCRE 正则表达式实际上让你用 (?|some(capture)|another(capture))
语法来做到这一点:
ip=(?|0\.0\.0\.0.*?host=(\S+)|(\d+\.\d+\.\d+\.\d+))
您可以从 debuggex visualisation that both groups are numbered 1. And on regex101 中看到右侧的捕获。
或者(如果您不使用 PCRE),我想您可以这样做。它不那么严格,但适用于大多数引擎。您当前的正则表达式对 IP 格式不是特别严格(允许大于 255 的数字等),所以这对您来说可能不是问题。
ip=(?:0\.0\.0\.0.*?host=)?(\S+)
使用交替,尝试从左到右:
(?<=ip)(?!0.0.0.0)\S+|(?<=host=)\S+
见demo
由于使用环顾四周,这仅匹配您的目标输入。消极的展望决定不使用 ip 如果它全部为零。
只选择 第一个 匹配项。