Primero, quiero estar de acuerdo con los demás en que la expresión regular o las str.translate(...)
soluciones basadas son más eficaces. Para mi caso de uso, el rendimiento de esta función no fue significativo, por lo que quería agregar ideas que consideraba con ese criterio.
Mi objetivo principal era generalizar las ideas de algunas de las otras respuestas en una solución que pudiera funcionar para cadenas que contengan más que palabras de expresión regular (es decir, poner en una lista negra el subconjunto explícito de caracteres de puntuación frente a caracteres de palabras en la lista blanca).
Tenga en cuenta que, en cualquier enfoque, uno también podría considerar el uso string.punctuation
en lugar de una lista definida manualmente.
Opción 1 - re.sub
Me sorprendió ver que no hay respuesta hasta ahora utiliza re.sub (...) . Me parece un enfoque simple y natural para este problema.
import re
my_str = "Hey, you - what are you doing here!?"
words = re.split(r'\s+', re.sub(r'[,\-!?]', ' ', my_str).strip())
En esta solución, anidé la llamada al re.sub(...)
interior re.split(...)
, pero si el rendimiento es crítico, compilar la expresión regular en el exterior podría ser beneficioso, para mi caso de uso, la diferencia no fue significativa, por lo que prefiero la simplicidad y la legibilidad.
Opción 2 - reemplazo de str.
Estas son algunas líneas más, pero tiene la ventaja de ser expansible sin tener que verificar si necesita escapar de cierto carácter en expresiones regulares.
my_str = "Hey, you - what are you doing here!?"
replacements = (',', '-', '!', '?')
for r in replacements:
my_str = my_str.replace(r, ' ')
words = my_str.split()
Hubiera sido agradable poder asignar el str.replace a la cadena en su lugar, pero no creo que se pueda hacer con cadenas inmutables, y aunque el mapeo contra una lista de caracteres funcionaría, ejecutar cada reemplazo contra cada carácter Suena excesivo. (Editar: consulte la siguiente opción para ver un ejemplo funcional).
Opción 3 - functools.reduce
(En Python 2, reduce
está disponible en el espacio de nombres global sin importarlo desde functools).
import functools
my_str = "Hey, you - what are you doing here!?"
replacements = (',', '-', '!', '?')
my_str = functools.reduce(lambda s, sep: s.replace(sep, ' '), replacements, my_str)
words = my_str.split()