多行文本的粗略正则表达式,在每场比赛结束时带有可选组和命名捕获
Rough regex for multiline text with optional group and named captures at the end of each match
我想捕获一些 ifconfig 输出(下面的示例),并从中获取接口名称、标志、IP 地址和网络掩码(如果存在)、状态(环回设备中也可能不存在)
re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
ether 00:30:18:c6:03:f0
inet 192.168.16.67 netmask 0xffffff00 broadcast 192.168.16.255
inet6 fe80::230:18ff:fec6:3f0%re0 prefixlen 64 scopeid 0x1
nd6 options=23<PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL>
media: Ethernet autoselect (1000baseT <full-duplex>)
status: active
re1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
ether 00:30:18:c6:03:f1
inet6 fe80::230:18ff:fec6:3f1%re1 prefixlen 64 scopeid 0x2
nd6 options=23<PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL>
media: Ethernet autoselect (none)
status: no carrier
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x3
inet 127.0.0.1 netmask 0xff000000
nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
我一直坚持到现在;
^(?<interface>(?:[^\s:]+))(?=: flags):\s(?:flags=\d+<(?<flags>(?:[\w,]+))>).*?(?:(?:inet (?<ip_address>(?:\d+\.?){4})|$)? (?:netmask 0x(?<netmask>(?:\w++\.?))|$)).*?(?:status: (?<status>(?:[\w ]++)))
但是由于状态行,这只会捕获普通接口而不是环回设备。如果您通过在状态行匹配组的末尾放置一个问号来使状态行可选,即使由于某些我无法理解的原因存在状态行,它也不匹配。
一个问题,等待全世界的天才来解决:)
您可以尝试此修复:
^(?<interface>(?:[^\s:]+)):\s+(?:flags=\d+<(?<flags>(?:[\w,]+))>)(?:(?!\b(?:flags=|inet\b|status:)).)*(?:(?:inet\s+(?<ip_address>(?:\d+\.?){4})|$)?\s+(?:netmask\s+0x(?<netmask>(?:\w++\.?))|$))(?:(?!status:|\binet\b|^[^\s:]+:\s+flags=\d+).)*(?:status:\s+(?<status>(?:[\w ]+)))?
我修改的要点:
- 删除了不必要的预读
(?=: flags)
- 添加了
(?:(?!status:|^[^\s:]+:\s+flags=\d+).)*
而不是最后一个 .*?
(具有 tempered greedy token 的特点,使我们可以只匹配我们需要的)
- 为最后一个
status
捕获组添加了 ?
量词。
见demo
我想捕获一些 ifconfig 输出(下面的示例),并从中获取接口名称、标志、IP 地址和网络掩码(如果存在)、状态(环回设备中也可能不存在)
re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
ether 00:30:18:c6:03:f0
inet 192.168.16.67 netmask 0xffffff00 broadcast 192.168.16.255
inet6 fe80::230:18ff:fec6:3f0%re0 prefixlen 64 scopeid 0x1
nd6 options=23<PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL>
media: Ethernet autoselect (1000baseT <full-duplex>)
status: active
re1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
ether 00:30:18:c6:03:f1
inet6 fe80::230:18ff:fec6:3f1%re1 prefixlen 64 scopeid 0x2
nd6 options=23<PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL>
media: Ethernet autoselect (none)
status: no carrier
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x3
inet 127.0.0.1 netmask 0xff000000
nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
我一直坚持到现在;
^(?<interface>(?:[^\s:]+))(?=: flags):\s(?:flags=\d+<(?<flags>(?:[\w,]+))>).*?(?:(?:inet (?<ip_address>(?:\d+\.?){4})|$)? (?:netmask 0x(?<netmask>(?:\w++\.?))|$)).*?(?:status: (?<status>(?:[\w ]++)))
但是由于状态行,这只会捕获普通接口而不是环回设备。如果您通过在状态行匹配组的末尾放置一个问号来使状态行可选,即使由于某些我无法理解的原因存在状态行,它也不匹配。
一个问题,等待全世界的天才来解决:)
您可以尝试此修复:
^(?<interface>(?:[^\s:]+)):\s+(?:flags=\d+<(?<flags>(?:[\w,]+))>)(?:(?!\b(?:flags=|inet\b|status:)).)*(?:(?:inet\s+(?<ip_address>(?:\d+\.?){4})|$)?\s+(?:netmask\s+0x(?<netmask>(?:\w++\.?))|$))(?:(?!status:|\binet\b|^[^\s:]+:\s+flags=\d+).)*(?:status:\s+(?<status>(?:[\w ]+)))?
我修改的要点:
- 删除了不必要的预读
(?=: flags)
- 添加了
(?:(?!status:|^[^\s:]+:\s+flags=\d+).)*
而不是最后一个.*?
(具有 tempered greedy token 的特点,使我们可以只匹配我们需要的) - 为最后一个
status
捕获组添加了?
量词。
见demo