如何查找子字符串的所有匹配项?

2024-05-01 22:12:14 发布

您现在位置:Python中文网/ 问答频道 /正文

Python有string.find()string.rfind()来获取字符串中子字符串的索引。

我想知道是否有类似string.find_all()的东西可以返回所有找到的索引(不仅是从头开始的第一个索引,还是从末尾开始的第一个索引)。

例如:

string = "test test test test"

print string.find('test') # 0
print string.rfind('test') # 15

#this is the goal
print string.find_all('test') # [0,5,10,15]

Tags: the字符串teststringisallfindthis
3条回答

没有一个简单的内置字符串函数可以满足您的要求,但是您可以使用更强大的regular expressions

import re
[m.start() for m in re.finditer('test', 'test test test test')]
#[0, 5, 10, 15]

如果要查找重叠匹配项,lookahead将执行以下操作:

[m.start() for m in re.finditer('(?=tt)', 'ttt')]
#[0, 1]

如果要反向查找所有不重叠的内容,可以将正向和负向展望组合成如下表达式:

search = 'tt'
[m.start() for m in re.finditer('(?=%s)(?!.{1,%d}%s)' % (search, len(search)-1, search), 'ttt')]
#[1]

^{}返回一个generator,因此您可以将上面的[]更改为(),以获得一个生成器,而不是一个列表,如果只对结果进行一次迭代,那么该列表将更有效。

这里有一个(非常低效的)方法来获得所有(即,甚至重叠)匹配:

>>> string = "test test test test"
>>> [i for i in range(len(string)) if string.startswith('test', i)]
[0, 5, 10, 15]
>>> help(str.find)
Help on method_descriptor:

find(...)
    S.find(sub [,start [,end]]) -> int

因此,我们可以自己建造:

def find_all(a_str, sub):
    start = 0
    while True:
        start = a_str.find(sub, start)
        if start == -1: return
        yield start
        start += len(sub) # use start += 1 to find overlapping matches

list(find_all('spam spam spam spam', 'spam')) # [0, 5, 10, 15]

不需要临时字符串或正则表达式。

相关问题 更多 >