如何查找所有出现的子字符串?

新手上路,请多包涵

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]


计算 出现次数,请参阅 计算字符串中子字符串的出现次数

原文由 nukl 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 331
2 个回答

没有简单的内置字符串函数可以满足您的需求,但您可以使用更强大的 正则表达式

 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]

re.finditer 返回一个 生成器,因此您可以将上面的 [] 更改为 () 以获得一个生成器而不是一个列表更高效只对结果进行一次迭代。

原文由 moinudin 发布,翻译遵循 CC BY-SA 4.0 许可协议

>>> 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]

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

原文由 Karl Knechtel 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题