Python 3 正则表达式 - 在字符串中查找所有重叠匹配项的开始和结束索引

python 3 regex - find all overlapping matches' start and end index in a string

提问人:Bjango 提问时间:4/1/2017 更新时间:4/1/2017 访问量:4155

问:

这是我最初的方法:

string = '1'*15     
result = re.finditer(r'(?=11111)', string)      # overlapped = True   
                                                # Doesn't work for me 
for i in result:                                # python 3.5
   print(i.start(), i.end())

它查找所有重叠的匹配项,但无法获得正确的结束索引。 输出:

1 <_sre.SRE_Match object; span=(0, 0), match=''>
2 <_sre.SRE_Match object; span=(1, 1), match=''>
3 <_sre.SRE_Match object; span=(2, 2), match=''>
4 <_sre.SRE_Match object; span=(3, 3), match=''>
(and so on..)

我的问题:如何找到所有重叠的匹配项,并正确获取所有开始和结束索引?

Python 正则表达式

评论


答:

12赞 Wiktor Stribiżew 4/1/2017 #1

你遇到的问题与以下事实有关:前瞻是一个零宽度的断言,它不消耗(即添加到匹配结果中)文本。它只是字符串中的一个位置。因此,您的所有匹配项都在字符串中的同一位置开始和结束。

您需要将前瞻模式与捕获组(即 )括起来,并访问 1 的开始和结束(带有 和):(?=(11111))i.start(1)i.end(1)

import re
s = '1'*15     
result = re.finditer(r'(?=(11111))', s)

for i in result:
    print(i.start(1), i.end(1))

查看 Python 演示,其输出是

(0, 5)
(1, 6)
(2, 7)
(3, 8)
(4, 9)
(5, 10)
(6, 11)
(7, 12)
(8, 13)
(9, 14)
(10, 15)

评论

0赞 Bjango 4/1/2017
为什么你必须在“i.start(1)”和“i.end(1)”中输入一个“1”?在我的脑海中,“i.start()”应该足够了,显然不是。
0赞 Wiktor Stribiżew 4/1/2017
您需要获取第 1 组值的起始和结束位置。 = ,整个比赛开始位置。匹配项是一个空字符串,即字符串中的一个位置,但捕获组保存实际值。i.start()i.start(0)
0赞 pippo1980 1/27/2023
@WiktorStribiżew我有一个更复杂的序列要找到:r'(?=(ATG(?:...)*?)(?=TAG|TGA|TAA))' .我可以用 start(1)、end(1) 或 span(1) 获得正确的开始和结束,我的问题是我如何找到正确的匹配(字符串)。结果给出空匹配项:match=''(即:(4056, 4152), 4056, 4152, <re.匹配对象;span=(4056, 4056), match=''>)
1赞 Wiktor Stribiżew 1/27/2023
@pippo1980 使用此类正则表达式时,整个匹配值将始终为空。您需要使用 ,或者re.findall[x.group(1) for x in re.finditer(pattern, text)]
0赞 Grzegorz Skibinski 5/15/2023
这仅适用于 OP 提供的示例,其中我们在模式中有恒定数量的字符。例如,考虑 和(我知道概括不是强制性的,但这个答案在其他几个问题上被引用,有类似的匹配样本 - 给人的印象,它是通用的)。s='1222122112221112221'list(map(lambda x: x.group(1), re.finditer(r'(?=(1(.*)1))', s)))
-1赞 gr8tech 4/1/2017 #2

您能否与此实现进行比较,看看差异可能在哪里。

match = re.finditer(r'111','test111 end111 and another 111')
for i in match:
    print(i.start(),i.end()

如果这对您不起作用,请分享您的数据样本

评论

2赞 Bjango 4/1/2017
我甚至不需要运行它就能知道这不是我想要的。