Python 使用findall()和search()时出现奇怪的正则表达式问题

Python 使用findall()和search()时出现奇怪的正则表达式问题,python,regex,python-2.7,search,findall,Python,Regex,Python 2.7,Search,Findall,我试图使用\w{2}\d/\d{1,2}(/\d{1,2})来匹配Cisco交换机上的以下两个接口: Gi1/0/1 Fa0/1 当我使用re.search()时,它返回所需的输出 import re port = "Gi1/0/1 Fa0/1" search = re.search(r'\w{2}\d/\d{1,2}(/\d{1,2})?', port) print search.group() 我得到“Gi1/0/1”作为输出 当我使用re.findall()时 我得到了不想要的“['

我试图使用\w{2}\d/\d{1,2}(/\d{1,2})来匹配Cisco交换机上的以下两个接口:

Gi1/0/1

Fa0/1

  • 当我使用re.search()时,它返回所需的输出

    import re
    port = "Gi1/0/1 Fa0/1"
    search = re.search(r'\w{2}\d/\d{1,2}(/\d{1,2})?', port)
    print search.group()
    
  • 我得到“Gi1/0/1”作为输出

  • 当我使用re.findall()时

  • 我得到了不想要的“['/1',']”

    为什么findall()不返回['Gi1/0/1','Fa0/1']

    这是因为我使用了(/\d{1,2}),而findall()应该返回这个部分吗?为什么呢

    我们如何使用findall()从文档中获取['Gi1/0/1','Fa0/1']

    如果模式中存在一个或多个组,则返回 组;如果模式有多个元组,这将是一个元组列表 小组

    在正则表达式中有一个捕获组
    (/\d{1,2})?

    您可以将其改为非捕获组
    (?:/\d{1,2})?

    您的正则表达式如下所示:

    search.group()
    返回正则表达式
    \w{2}\d/\d{1,2}(/\d{1,2})找到的整个匹配项。
    。考虑到捕获组,< <强> > < >强>。它相当于
    search.group(0)
    。使用
    search.group(1)
    时,它将返回
    /1
    :第一个捕获组的结果

    另一方面,
    re.findall
    返回匹配组的所有结果。要获得预期的结果,您的正则表达式应该

    (\w{2}\d/(?:\d{1,2}/)?\d{1,2})
    
    Python代码

    正则表达式分解


    p.S.从你的问题来看,我认为你只匹配字母表。在这种情况下,如果您希望使用正则表达式,请使用,
    [A-Za-z]
    而不是
    \w

    ;这将有助于:

    search = re.findall(r'\w{2}\d/\d{1}(?:/\d{1})?', port)
    
    您也可以这样做:

    >>> "Gi1/0/1 Fa0/1".split(' ')
    ['Gi1/0/1', 'Fa0/1']
    

    非常感谢,我将尝试这个技巧,使其成为非捕获组。非常感谢您的详细回复,我学到了一些新的东西,非常感谢!谢谢你的回答。接口名称因Cisco交换机型号而异,有些型号为千兆以太网,有些型号为快速以太网。我有另一个更大的脚本来捕获不同交换机上的这些接口。这里我只是提供了一个示例代码来理解search()和findall()之间的区别。我理解。
    >>> re.findall(r'(\w{2}\d/(?:\d{1,2}/)?\d{1,2})', port)
    ['Gi1/0/1', 'Fa0/1']
    
    ( #Start Capturing group
      \w{2}\d/  #Match two characters in [A-Za-z0-9_] followed by a digit and slash
      (?:\d{1,2}/)? #Followed by two digits which are optional
      \d{1,2} #Followed by two digits
    ) #End capturing group
    
    search = re.findall(r'\w{2}\d/\d{1}(?:/\d{1})?', port)
    
    >>> "Gi1/0/1 Fa0/1".split(' ')
    ['Gi1/0/1', 'Fa0/1']