Sustituya múltiples espacios en blanco por espacios en blanco únicos en Python [duplicado]
Tengo esta cadena:
mystring = 'Here is some text I wrote '
¿Cómo puedo sustituir los caracteres de espacio en blanco doble, triple (...) por un solo espacio, para obtener:
mystring = 'Here is some text I wrote'
Una posibilidad simple (si prefiere evitar los RE) es
' '.join(mystring.split())
La división y la unión realizan la tarea sobre la que estás preguntando explícitamente; además, también hacen la tarea adicional de la que no hablas pero que se ve en tu ejemplo, eliminando los espacios finales ;-).
Se puede utilizar una expresión regular para ofrecer más control sobre los caracteres de espacio en blanco que se combinan.
Para hacer coincidir los espacios en blanco Unicode:
import re
_RE_COMBINE_WHITESPACE = re.compile(r"\s+")
my_str = _RE_COMBINE_WHITESPACE.sub(" ", my_str).strip()
Para que coincida únicamente con espacios en blanco ASCII:
import re
_RE_COMBINE_WHITESPACE = re.compile(r"(?a:\s+)")
_RE_STRIP_WHITESPACE = re.compile(r"(?a:^\s+|\s+$)")
my_str = _RE_COMBINE_WHITESPACE.sub(" ", my_str)
my_str = _RE_STRIP_WHITESPACE.sub("", my_str)
A veces es esencial hacer coincidir solo los espacios en blanco ASCII para mantener caracteres de control como x0b, x0c, x1c, x1d, x1e, x1f.
Referencia:
Acerca de \s
:
Para patrones Unicode (str): coincide con los caracteres de espacios en blanco Unicode (que incluyen [ \t\n\r\f\v] y también muchos otros caracteres, por ejemplo, los espacios sin separación exigidos por las reglas tipográficas en muchos idiomas). Si se utiliza el indicador ASCII, solo coincide [ \t\n\r\f\v].
Acerca de re.ASCII
:
Haga que \w, \W, \b, \B, \d, \D, \s y \S realicen una coincidencia solo ASCII en lugar de una coincidencia Unicode completa. Esto sólo tiene sentido para los patrones Unicode y se ignora para los patrones de bytes. Corresponde a la bandera en línea (?a).
strip()
eliminará los espacios en blanco iniciales y finales.
Para completar, también puede utilizar:
mystring = mystring.strip() # the while loop will leave a trailing space,
# so the trailing whitespace must be dealt with
# before or after the while loop
while ' ' in mystring:
mystring = mystring.replace(' ', ' ')
que funcionará rápidamente en cadenas con relativamente pocos espacios (más rápido que re
en estas situaciones).
En cualquier escenario, la solución de división/unión de Alex Martelli funciona al menos con la misma rapidez (normalmente mucho más).
En su ejemplo, usando los valores predeterminados de timeit.Timer.repeat(), obtengo los siguientes tiempos:
str.replace: [1.4317800167340238, 1.4174888149192384, 1.4163512401715934]
re.sub: [3.741931446594549, 3.8389395858970374, 3.973777672860706]
split/join: [0.6530919432498195, 0.6252146571700905, 0.6346594329726258]
EDITAR:
Acabo de encontrar esta publicación que ofrece una comparación bastante larga de las velocidades de estos métodos.