Python 用于IPv4匹配的正则表达式
我试图使用正则表达式匹配IPv4地址。我有下面的正则表达式 但我不能理解:在它里面 我知道?:是为了避免捕获一个群体,但在这里我无法理解它 更新: 如果我删除?:,我将得到以下结果。我想我会得到IP地址和元组中捕获的组Python 用于IPv4匹配的正则表达式,python,regex,Python,Regex,我试图使用正则表达式匹配IPv4地址。我有下面的正则表达式 但我不能理解:在它里面 我知道?:是为了避免捕获一个群体,但在这里我无法理解它 更新: 如果我删除?:,我将得到以下结果。我想我会得到IP地址和元组中捕获的组 >>> re.findall(r'((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)', txt) [('11.', '11', '13'), (
>>> re.findall(r'((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)', txt)
[('11.', '11', '13'), ('11.', '11', '14'), ('12.', '12', '13'), ('12.', '12', '14'), ('11.', '11', '13'), ('11.', '11', '14'), ('12.', '12', '13')]
正如我在评论中所说的,如果您不使用非捕获组而不是匹配整个正则表达式,那么由于这一点,您的正则表达式中有3个组,每个IP将得到3个结果 有关更好的演示,请参阅以下状态机: 没有非捕获组:
((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)
(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)
使用非捕获组:
((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)
(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)
正如您所看到的,当您起诉非捕获组时,您没有任何组,整个正则表达式将解释为一个组,通常是组0 在这种情况下需要非捕获组,因为IPv4四重奏的{3}重复说明符只返回第三个匹配项。然而,外部组将提供所有3个匹配的内部匹配:q{3},其中q=regex表示四重奏中的一个数字。但是,我们希望隐藏内部组的第三个匹配项,该匹配项使用非捕获说明符 请参阅下文,了解没有非捕获的正则表达式、问题和解决方案
q = r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'
在不捕获的情况下再现{3}重复问题:
t = '(%s\.){3}%s' % (q,q)
>>> re.findall(t,txt)
[('11.', '11', '13'), ('11.', '11', '14')]
如果要单独捕获元组,请执行以下操作:
s='{0}\.{0}\.{0}\.{0}'.format(q)
>>> re.findall(s, txt)
[('254', '123', '11', '13'), ('254', '123', '11', '14')]
或
为什么要对这个问题投反对票?正如你所说,无捕获组令牌是为了避免捕获组。在这种情况下,使用它的全部目的就是为了避免捕获组。我认为,在这种情况下,你不会将它与整个IP一起用于每个IP,你会得到另一个额外的部分。否决票是因为你已经回答了你的问题@我添加了一个更新。当我删除?:,我没有得到IP地址。我不确定您是否对正则表达式很挑剔,但另一个解决方案是: