Python的re.search()没有返回完整的组匹配结果

4
import re

ip6 = "1234:0678:0000:0000:00cd:0000:0000:0000"
zeroes = re.search("(:?0000)+", ip6)
print zeroes.group(0)

:0000:0000

我正在尝试查找由冒号分隔的四个零的最长序列。字符串包含三个这样的组序列,但只有两个组被打印出来了。为什么呢?

编辑:它打印 :0000:0000 是因为那是字符串中的第一个匹配项 - 但是我认为正则表达式总是寻找最长匹配吗?


将 (^0000|:0000) 改为 (:?0000) - John Gordon
实际上,NFA正则表达式引擎(例如Python中的引擎)总是返回“最长、最左侧”的匹配。 - ridgerunner
@ridgerunner 这个的来源是什么? - tdenniston
2
@denniston.t 这在Jeffrey Friedl的《精通正则表达式》中有解释。除非正则表达式引擎先找到 所有 匹配项,然后选择其中最长的那个,否则它会自然地给出 第一个 匹配项,无论它是否是所有匹配项中最长的。在字符串中给定位置开始的所有匹配项中,它确实会给出最长的匹配项,除非您使用 *? 等非贪婪运算符。 - drmirror
@denniston.t - 我是从精通正则表达式(第三版)中得到的,就像drmirror所解释的那样。 - ridgerunner
3个回答

2

更新回答以适用于Python 2.6:

p = re.compile('((:?0000)+)')
longestword = ""
for word in p.findall(ip6):
    if len(word[0])>len(longestword):
        longestword = word[0]
print longestword

那个列表推导式在等号处给了我一个语法错误。这是Python3的问题吗? - John Gordon
这在我的 Python 3 实例中不起作用,所以我认为它不是。 - Adam Wagner
是的,我刚在我的解释器中测试了它,但它没有起作用,所以我写了一个不使用列表推导式的解决方案。 - silleknarf
1
Python不允许在表达式中进行赋值操作。原因是在其他语言中常见的使用“=”而实际上想要使用“==”这个常见错误。 - Brigand
我实际上是想赋值,但我不知道我不能在列表推导式中这样做。谢谢你指出了这一点。 - silleknarf

2

如果您不依赖于正则表达式,您可以使用 itertools.groupby

from itertools import groupby

ip6 = "1234:0678:0000:0000:00cd:0000:0000:0000"

longest = 0
for section, elems in groupby(ip6.split(':')):
    if section == '0000':
        longest = len(list(elems))

print longest  # Prints '3', the number of times '0000' repeats the most.
               # you could, of course, generate a string of 0000:... from this

我相信这可以被简化成更加优雅的形式,但我认为这传达了重点。


0

我正在使用Python 2.7.3
用re.finditer()怎么样?

$ uname -r
3.2.0-4-amd64


#!/usr/bin/env python

import re

ip6 = "1234:0678:0000:0000:00cd:0000:0000:0000"

iters = re.finditer("(:?0000)+", ip6)
for match in iters:
    print 'match.group()  -> ',match.group()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接