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]
要统计出现次数,请参见计算字符串中子字符串出现的次数。
来,让我们一起递归。
def locations_of_substring(string, substring):
"""Return a list of locations of a substring."""
substring_length = len(substring)
def recurse(locations_found, start):
location = string.find(substring, start)
if location != -1:
return recurse(locations_found + [location], location+substring_length)
else:
return locations_found
return recurse([], 0)
print(locations_of_substring('this is a test for finding this and this', 'this'))
# prints [0, 27, 36]
不需要这样使用正则表达式。
这个函数不会查看字符串内的所有位置,它不会浪费计算资源。我的尝试:
def findAll(string,word):
all_positions=[]
next_pos=-1
while True:
next_pos=string.find(word,next_pos+1)
if(next_pos<0):
break
all_positions.append(next_pos)
return all_positions
要使用它,可以这样调用它:
result=findAll('this word is a big word man how many words are there?','word')
没有简单的内置字符串函数来做你正在寻找的事情,但你可以使用更强大的正则表达式:
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]
如果你想要一个没有重叠的反向查找-all,你可以将正负前向组合成这样的表达式:
search = 'tt'
[m.start() for m in re.finditer('(?=%s)(?!.{1,%d}%s)' % (search, len(search)-1, search), 'ttt')]
#[1]
red .finditer返回一个生成器,因此您可以将上面的[]更改为()以获得一个生成器,而不是一个列表,如果您只迭代一次结果,这将更有效。
当在一份文件中寻找大量的关键词时,使用flash文本
from flashtext import KeywordProcessor
words = ['test', 'exam', 'quiz']
txt = 'this is a test'
kwp = KeywordProcessor()
kwp.add_keywords_from_list(words)
result = kwp.extract_keywords(txt, span_info=True)
在大量搜索词列表上,Flashtext比正则表达式运行得更快。