【问题标题】:Python regex find all overlapping matches?Python regex 找到所有重叠的匹配项?
【发布时间】:2011-08-02 18:36:40
【问题描述】:

我试图在 Python 2.6 中使用 re 在更大的数字系列中查找每 10 位数字系列。

我很容易抓住没有重叠的匹配,但我想要数字系列中的每一个匹配。例如。

在“123456789123456789”中

我应该得到以下列表:

[1234567891,2345678912,3456789123,4567891234,5678912345,6789123456,7891234567,8912345678,9123456789]

我发现了对“前瞻”的引用,但我看到的示例仅显示成对的数字,而不是更大的分组,而且我无法将它们转换为超过两位数。

【问题讨论】:

  • 当重叠匹配从同一点开始时,所提出的解决方案将不起作用,例如,匹配 "a|ab|abc" 和 "abcd" 只会返回一个结果。是否有不涉及多次调用 match() 手动跟踪“结束”边界的解决方案?
  • @VítorDeAraújo:像(a|ab|abc) 这样的重叠正则表达式通常可以重写为具有嵌套捕获组的非重叠正则表达式,例如(a(b(c)?)?)?,我们在解包匹配项时忽略除最外层(即最左边)之外的所有捕获组;诚然,这有点痛苦,而且不太清晰。这也将是一个性能更高的正则表达式来匹配。

标签: python regex overlapping


【解决方案1】:

在前瞻中使用捕获组。前瞻捕获您感兴趣的文本,但实际匹配在技术上是前瞻之前的零宽度子字符串,因此匹配在技术上是不重叠的:

import re 
s = "123456789123456789"
matches = re.finditer(r'(?=(\d{10}))',s)
results = [int(match.group(1)) for match in matches]
# results: 
# [1234567891,
#  2345678912,
#  3456789123,
#  4567891234,
#  5678912345,
#  6789123456,
#  7891234567,
#  8912345678,
#  9123456789]

【讨论】:

  • 我的回答至少比这个快2倍。但这个解决方案很棘手,我赞成。
  • 解释 = 不是搜索模式(10 位数字),而是搜索模式后面的任何内容。所以它找到字符串的位置 0,字符串的位置 1,依此类推。然后它抓取 group(1) - 匹配模式并列出这些模式。非常酷。
  • 我加入了 StackOverflow,回答了问题,并提高了我的声誉,这样我就可以为这个答案投票。我现在坚持使用 Python 2.4,所以我不能使用 Python 3 的更高级的正则表达式函数,而这正是我正在寻找的那种奇怪的诡计。
  • 您能否在代码中添加更多解释。根据 Stack Overflow,它不是最好的方法,只是在答案中包含代码。它肯定会帮助人们。
  • 这真的很有帮助。谢谢:D
【解决方案2】:

我喜欢正则表达式,但这里不需要它们。

简单

s =  "123456789123456789"

n = 10
li = [ s[i:i+n] for i in xrange(len(s)-n+1) ]
print '\n'.join(li)

结果

1234567891
2345678912
3456789123
4567891234
5678912345
6789123456
7891234567
8912345678
9123456789

【讨论】:

  • 这里只是不需要正则表达式,因为您正在“在更大的数字系列中”应用特殊知识,因此您已经知道每个位置 0 <= i < len(s)-n+1 保证是 10-数字匹配。此外,我认为您的代码可以加快速度,对代码高尔夫来说会很有趣。
【解决方案3】:

您也可以尝试使用支持重叠匹配的third-party regex module(不是re)。

>>> import regex as re
>>> s = "123456789123456789"
>>> matches = re.findall(r'\d{10}', s, overlapped=True)
>>> for match in matches: print(match)  # print match
...
1234567891
2345678912
3456789123
4567891234
5678912345
6789123456
7891234567
8912345678
9123456789

【讨论】:

  • 我得到:TypeError: findall() got an unexpected keyword argument 'overlapped'
  • @Carsten:你首先需要安装regex模块:pip install regex
  • 成功了,谢谢。如果没有安装正则表达式,我会认为我会收到一个导入错误
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多