您不必使用re
在这里你可以使用itertools
模块而是节省大量的内存。
您可以先提取所有子串长度为4,然后将它们与你的substring
比较,只是选择那些与你substring
小于2的区别:
from itertools import izip,islice,tee
def sub_findre(s,substring,diffnumber):
sublen=len(substring)
zip_gen=(izip(substring,islice(s,i,i+sublen)) for i in xrange(len(s)))
for z in zip_gen:
l,z=tee(z)
if sum(1 for i,j in l if i==j)>=sublen-diffnumber:
new=izip(*z)
next(new)
yield ''.join(next(new))
演示:
s='SSPQQQQPSSSSQQQSSQPSPSQSSQPSSQPPSSSSQPSPSQSSQPSSSSQPSPSQSSQPSSSSQPSPSQ'
substring='SSQP'
print list(sub_findre(s,substring,2))
['SSPQ', 'SPQQ', 'QQQP', 'SSSS', 'SSSQ', 'SSQQ', 'SQQQ', 'SSQP', 'PSQS', 'SSQP', 'SSQP', 'SQPP', 'SSSS', 'SSSQ', 'SSQP', 'PSQS', 'SSQP', 'SSSS', 'SSSQ', 'SSQP', 'PSQS', 'SSQP', 'SSSS', 'SSSQ', 'SSQP', 'PSQ']
如果您想要返回索引,您需要将索引放入izip
,您可以使用itertools.repeat()
重复长度为substring
的索引:
from itertools import izip,islice,tee,repeat
def sub_findre(s,substring,diffnumber):
sublen=len(substring)
zip_gen=(izip(substring,islice(s,i,i+sublen),repeat(i,sublen)) for i in xrange(len(s)))
for z in zip_gen:
l,z=tee(z)
if sum(1 for i,j,_ in l if i==j)>=sublen-diffnumber:
new=izip(*z)
next(new)
next(new)
yield next(new)[0]
演示:
print list(sub_findre(s,substring,2))
[0, 1, 4, 8, 9, 10, 11, 15, 20, 23, 27, 28, 32, 33, 34, 39, 42, 46, 47, 48, 53, 56, 60, 61, 62, 67]
确实,正则表达式只是完全使用的错误工具。对于20个中的2个错误,模式中会有190个替代项。 –
你能否返回索引号,类似于200_success的'match.start(0)'技巧? – warship
@军舰签出编辑! – Kasramvd