¿Cómo encontrar todas las apariciones de una subcadena?
Python tiene string.find()
ystring.rfind()
para obtener el índice de una subcadena en una cadena.
Me pregunto si hay algo comostring.find_all()
que pueda devolver todos los índices encontrados (no solo el primero desde el principio o el primero desde el final).
Por ejemplo:
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]
Para contar las apariciones, consulte Contar el número de apariciones de una subcadena en una cadena .
No existe una función de cadena incorporada simple que haga lo que estás buscando, pero puedes usar las expresiones regulares más poderosas :
import re
[m.start() for m in re.finditer('test', 'test test test test')]
#[0, 5, 10, 15]
Si desea encontrar coincidencias superpuestas, la búsqueda anticipada lo hará:
[m.start() for m in re.finditer('(?=tt)', 'ttt')]
#[0, 1]
Si desea buscar todo inverso sin superposiciones, puede combinar búsqueda anticipada positiva y negativa en una expresión como esta:
search = 'tt'
[m.start() for m in re.finditer('(?=%s)(?!.{1,%d}%s)' % (search, len(search)-1, search), 'ttt')]
#[1]
re.finditer
devuelve un generador , por lo que puede cambiar lo []
anterior para ()
obtener un generador en lugar de una lista, lo que será más eficiente si solo itera los resultados una vez.
>>> help(str.find)
Help on method_descriptor:
find(...)
S.find(sub [,start [,end]]) -> int
Así, podemos construirlo nosotros mismos:
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]
No se requieren cadenas temporales ni expresiones regulares.