separar - reemplazar caracteres en python
Encuentra todas las apariciones de una subcadena en Python (15)
Python tiene string.find()
y string.rfind()
para obtener el índice de una subcadena en string.
Me pregunto, tal vez hay algo como string.find_all()
que puede devolver todos los índices fundados (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
#that''s the goal
print string.find_all(''test'') # [0,5,10,15]
Aquí hay una forma (muy ineficiente) de obtener todas las coincidencias (es decir, incluso superpuestas):
>>> string = "test test test test"
>>> [i for i in range(len(string)) if string.startswith(''test'', i)]
[0, 5, 10, 15]
Cualquiera que sea la solución provista por otros, está completamente basada en el método disponible find () o en cualquier método disponible.
¿Cuál es el algoritmo básico básico para encontrar todas las apariciones de una subcadena en una cadena?
def find_all(string,substring):
"""
Function: Returning all the index of substring in a string
Arguments: String and the search string
Return:Returning a list
"""
length = len(substring)
c=0
indexes = []
while c < len(string):
if string[c:c+length] == substring:
indexes.append(c)
c=c+1
return indexes
También puede heredar la clase str a la nueva clase y puede usar esta función a continuación.
class newstr(str):
def find_all(string,substring):
"""
Function: Returning all the index of substring in a string
Arguments: String and the search string
Return:Returning a list
"""
length = len(substring)
c=0
indexes = []
while c < len(string):
if string[c:c+length] == substring:
indexes.append(c)
c=c+1
return indexes
Llamando al método
newstr.find_all (''¿Le resulta útil esta respuesta? ¡Entonces, promueva esto!'', ''este'')
Cuando busque una gran cantidad de palabras clave en un documento, use flashtext
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 se ejecuta más rápido que las expresiones regulares en una gran lista de palabras de búsqueda.
Este hilo es un poco viejo pero esto funcionó para mí:
numberString = "onetwothreefourfivesixseveneightninefiveten"
testString = "five"
marker = 0
while marker < len(numberString):
try:
print(numberString.index("five",marker))
marker = numberString.index("five", marker) + 1
except ValueError:
print("String not found")
marker = len(numberString)
Esto hace el truco para mí usando re.finditer
import re
text = ''This is sample text to test if this pythonic ''/
''program can serve as an indexing platform for ''/
''finding words in a paragraph. It can give ''/
''values as to where the word is located with the ''/
''different examples as stated''
# find all occurances of the word ''as'' in the above text
find_the_word = re.finditer(''as'', text)
for match in find_the_word:
print(''start {}, end {}, search string /'{}/'''.
format(match.start(), match.end(), match.group()))
La forma pitónica sería:
mystring = ''Hello World, this should work!''
find_all = lambda c,s: [x for x in range(c.find(s), len(c)) if c[x] == s]
# s represents the search string
# c represents the character string
find_all(mystring,''o'') # will return all positions of ''o''
[4, 7, 20, 26]
>>>
No hay una simple función de cadena incorporada que haga lo que estás buscando, pero podrías 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, lookahead lo hará:
[m.start() for m in re.finditer(''(?=tt)'', ''ttt'')]
#[0, 1]
Si desea una búsqueda inversa de todo sin superposiciones, puede combinar lookahead positivo y negativo 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 generator , por lo que puede cambiar el []
de lo anterior a ()
para obtener un generador en lugar de una lista que será más eficiente si solo está iterando los resultados una vez.
Nuevamente, hilo viejo, pero aquí está mi solución usando un generador y un str.find
simple.
def findall(p, s):
''''''Yields all the positions of
the pattern p in the string s.''''''
i = s.find(p)
while i != -1:
yield i
i = s.find(p, i+1)
Ejemplo
x = ''banananassantana''
[(i, x[i:i+2]) for i in findall(''na'', x)]
devoluciones
[(2, ''na''), (4, ''na''), (6, ''na''), (14, ''na'')]
Puede utilizar re.finditer()
para coincidencias no superpuestas.
>>> import re
>>> aString = ''this is a string where the substring "is" is repeated several times''
>>> print [(a.start(), a.end()) for a in list(re.finditer(''is'', aString))]
[(2, 4), (5, 7), (38, 40), (42, 44)]
pero no funcionará para:
In [1]: aString="ababa"
In [2]: print [(a.start(), a.end()) for a in list(re.finditer(''aba'', aString))]
Output: [(0, 3)]
Puedes probar :
>>> string = "test test test test"
>>> for index,value in enumerate(string):
if string[index:index+(len("test"))] == "test":
print index
0
5
10
15
Si solo estás buscando un solo personaje, esto funcionaría:
string = "dooobiedoobiedoobie"
match = ''o''
reduce(lambda count, char: count + 1 if char == match else count, string, 0)
# produces 7
También,
string = "test test test test"
match = "test"
len(string.split(match)) - 1
# produces 4
Mi corazonada es que ninguno de estos (especialmente el # 2) es terriblemente eficaz.
Ven, vamos a hacer juntos la terapia.
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]
No hay necesidad de expresiones regulares de esta manera.
este es un hilo antiguo, pero me interesé y quería compartir mi solución.
def find_all(a_string, sub):
result = []
k = 0
while k < len(a_string):
k = a_string.find(sub, k)
if k == -1:
return result
else:
result.append(k)
k += 1 #change to k += len(sub) to not search overlapping results
return result
Debe devolver una lista de posiciones donde se encontró la subcadena. Por favor comente si ve un error o espacio para mejorar.
por favor mira el siguiente código
#!/usr/bin/env python
# coding:utf-8
''''''黄哥Python''''''
def get_substring_indices(text, s):
result = [i for i in range(len(text)) if text.startswith(s, i)]
return result
if __name__ == ''__main__'':
text = "How much wood would a wood chuck chuck if a wood chuck could chuck wood?"
s = ''wood''
print get_substring_indices(text, s)
>>> 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 o expresiones regulares.