¿Cómo encontrar todas las apariciones de una subcadena?

Resuelto nukl asked hace 13 años • 33 respuestas

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 .

nukl avatar Jan 12 '11 09:01 nukl
Aceptado

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.finditerdevuelve 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.

moinudin avatar Jan 12 '2011 02:01 moinudin
>>> 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.

Karl Knechtel avatar Jan 12 '2011 03:01 Karl Knechtel