Python re.match包含可选组None

时间:2019-04-15 20:35:19

标签: regex python-3.x

我正在尝试在for行循环中使用re.compile。重新编译后,在行上运行重新匹配。使用Regex101,我可以在组上获得正确的匹配,但是在python内部运行时,对于具有空字符串的组,它返回None。我追求的是即使组为空也要在组上进行匹配。

要匹配的字符串:

Interface          Status      Protocol    Description
BE1                up          up          
Mg0/RSP0/CPU0/0    up          up          NNI to Cat2960x G1/0/1
Te0/0/0/3          admin-down  admin-down  
Gi0/0/1/0          down        down        Test L2VPN
RP/0/RSP0/CPU0:LAB-9001-1#

最后一组(描述)应该是可选的,可以包含描述,也可以为空。这可以在Regex101中使用,并且此过滤器上有4个组:

^\s*(?:(?P<interface>[a-zA-Z0-9]\S+?))\s+(?:(?P<status>[up|admin\-down]\S+?))\s+(?:(?P<protocol>[up|admin\-down]\S+))\s+(?:(?P<description>(?<!^).*))

在代码上我正在使用编译和匹配,但是如果描述为空,则返回None,当我希望它返回前3组和第4组(描述)的空字符串时。

for line in result.splitlines():
            line = line.rstrip()

            p1 = re.compile(r'^\s*(?:(?P<interface>[a-zA-Z0-9]\S+?))\s+(?:(?P<status>[up|admin\-down]\S+?))\s+(?:(?P<protocol>[up|admin\-down]\S+))\s+(?P<description>(?<!^).*)')
            m = p1.match(line).groups()
            print(m)

对于任何空白的描述都不匹配。他们的语法可以告诉re.match包含空组吗?

1 个答案:

答案 0 :(得分:1)

您使用的正则表达式包含字符类而不是分组构造({[up|down]updown不匹配,它与up,{ {1}},|dow),最后一个模式部分必须匹配一个必填空格+任何字符,但您的n这条线,没有空间可以匹配。

固定的正则表达式看起来像

rstrip

请参见Regulex图:

enter image description here

详细信息

  • ^(?P<interface>[a-zA-Z0-9]\S*)\s+(?P<status>up|admin-down)\s+(?P<protocol>up|admin-down)(?:\s+(?P<description>.*))? -字符串的开头
  • ^-组“接口”:一个字母数字,后跟任意0+个非空格字符
  • (?P<interface>[a-zA-Z0-9]\S*)-超过1个空格
  • \s+-组“状态”:(?P<status>up|admin-down)up
  • admin-down-超过1个空格
  • \s+-组“协议”:(?P<protocol>up|admin-down)up
  • admin-down-可选组:
    • (?:\s+(?P<description>.*))?-超过1个空格
    • \s+-组“描述”:除换行符外,其他0个以上的字符

在Python中,您可以使用

(?P<description>.*)

请参见Python demo

请注意,如果您使用import re result = r"""Interface Status Protocol Description BE1 up up Mg0/RSP0/CPU0/0 up up NNI to Cat2960x G1/0/1 Te0/0/0/3 admin-down admin-down Gi0/0/1/0 down down Test L2VPN RP/0/RSP0/CPU0:LAB-9001-1#""" p1 = re.compile(r'(?P<interface>[a-zA-Z0-9]\S*)\s+(?P<status>up|admin-down)\s+(?P<protocol>up|admin-down)(?:\s+(?P<description>.*))?') for line in result.splitlines(): line = line.rstrip() m = p1.match(line) if m: print(m.groups()) ,则不需要字符串锚点的^开头。