使用 findall() 和 search() 的奇怪正则表达式问题
Strange regex issue using findall() and search()
我正在尝试使用 \w{2}\d/\d{1,2}(/\d{1,2})? 以便匹配 Cisco 交换机上的以下两个接口:
Gi1/0/1
Fa0/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" 作为输出。
当我使用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})?
你的正则表达式看起来像:
import re
port = "Gi1/0/1 Fa0/1"
search = re.findall(r'\w{2}\d/\d{1,2}(?:/\d{1,2})?', port)
print search
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']
我正在尝试使用 \w{2}\d/\d{1,2}(/\d{1,2})? 以便匹配 Cisco 交换机上的以下两个接口:
Gi1/0/1
Fa0/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" 作为输出。
当我使用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})?
你的正则表达式看起来像:
import re
port = "Gi1/0/1 Fa0/1"
search = re.findall(r'\w{2}\d/\d{1,2}(?:/\d{1,2})?', port)
print search
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']