用于多行文本的粗糙正则表达式,在每次匹配结束时使用可选组和命名捕获

时间:2015-06-30 14:45:57

标签: regex regex-greedy

我想捕获一些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 ]++)))

但由于状态行,这仅捕获普通接口而非环回设备。如果通过在状态行匹配组的末尾添加问号使状态行可选,则即使由于某些我无法理解的原因存在状态行,它也不匹配。

等待世界各地的天才解决问题的问题:)

1 个答案:

答案 0 :(得分:0)

您可以尝试此修复:

^(?<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 ]+)))?

我改变的要点:

  1. 删除了不必要的预见(?=: flags)
  2. 添加了(?:(?!status:|^[^\s:]+:\s+flags=\d+).)*而不是上一个.*?(以tempered greedy token为特色,只允许我们匹配到我们需要的内容)
  3. 为上一个?捕获组添加了status量词。
  4. 请参阅demo