查找所有正则表达式匹配项的索引?

112
我正在解析可能包含任意数量引号字符串的字符串(我正在解析代码,并尝试避免使用PLY)。我想知道一个子字符串是否被引用,并且我有子字符串的索引。我的最初想法是使用re来查找所有匹配项,然后确定它们代表的索引范围。
似乎我应该使用类似于\"[^\"]+\"|'[^']+'的正则表达式与re一起使用(我暂时避免处理三重引号之类的字符串)。当我使用findall()时,我会得到匹配字符串的列表,这很不错,但我需要索引。
我的子字符串可能像c这样简单,我需要弄清楚这个特定的c是否被引用。

似乎这个工作不适合使用正则表达式。 - Daniel Kluev
3个回答

225
这就是你想要的:(来源)
re.finditer(pattern, string[, flags]) 

返回一个迭代器,它产生MatchObject实例,这些实例是在字符串中所有不重叠的RE模式匹配中生成的。字符串从左到右进行扫描,并按找到的顺序返回匹配项。除非空匹配项接触到另一个匹配项的开头,否则会将其包含在结果中。

然后,您可以从MatchObjects中获取起始和结束位置。

例如:

[(m.start(0), m.end(0)) for m in re.finditer(pattern, string)]

56
请注意,你实际上可以使用 m.span() 来获取 (m.start(), m.end())(默认分组参数为 0,因此可以省略)。 - Amber
1
太棒了,我正好在寻找这个。 - armandino
6
注意,在这种情况下它失败了:base_str = "GATATATGCATATACTT",sub_str = "ATAT",结果应该是[(1,5), (3, 7), (9, 13)],但实际上只有[(1, 5), (9, 13)]。 - unionx
@unionx 如果你有更好的解决方案,这是你的选择。 - Burger King
6
根据文档,finditer() 返回不重叠的匹配项。 - Talia
2
一个更为近期的例子,使用了2018年的语法。 - Nathan majicvr.com

4
获取所有出现位置的索引:
S = input() # Source String 
k = input() # String to be searched
import re
pattern = re.compile(k)
r = pattern.search(S)
if not r: print("(-1, -1)")
while r:
    print("({0}, {1})".format(r.start(), r.end() - 1))
    r = pattern.search(S,r.start() + 1)

1
这应该解决您的问题:

pattern=r"(?=(\"[^\"]+\"|'[^']+'))"

然后使用以下代码获取所有重叠的索引:
indicesTuple = [(mObj.start(1),mObj.end(1)-1) for mObj in re.finditer(pattern,input)]

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