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

Strange regex issue using findall() and search()

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

Gi1/0/1

Fa0/1

  1. 当我使用 re.search() 时,它 return 得到了所需的输出。

    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" 作为输出。

  1. 当我使用re.findall()

    import re
    port = "Gi1/0/1 Fa0/1"
    search = re.findall(r'\w{2}\d/\d{1,2}(/\d{1,2})?', port)
    print search
    

我得到 "['/1', '']",这是不需要的。

为什么 findall() return ['Gi1/0/1','Fa0/1']?

是不是因为我用了(/\d{1,2})?,而findall()应该return这部分?这是为什么?

我们如何使用 findall() 得到 ['Gi1/0/1','Fa0/1']

来自 findall 文档

If one or more groups are present in the pattern, return a list of groups; this will be a list of tuples if the pattern has more than one group.

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

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

你的正则表达式看起来像:

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

import re
port = "Gi1/0/1 Fa0/1"
search = re.findall(r'\w{2}\d/\d{1,2}(?:/\d{1,2})?', port)
print search

Demo

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

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

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

Python代码

>>> 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

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']