2009-12-14 9 views
46

string.whitespace de Python es grande:Retire el espacio en blanco en Python usando string.whitespace

>>> string.whitespace 
'\t\n\x0b\x0c\r ' 

¿Cómo utilizar esto con una cadena sin recurrir a escribir manualmente en '\ t | \ n | ... etc. para regex?

Por ejemplo, debería poder activar: "Por favor, \ n no me duela \ x0b".

en

"Por favor, no me hagas daño."

Probablemente querría mantener los espacios simples, pero sería bastante fácil ir a string.whitespace [: - 1] Supongo.

Respuesta

142

Hay un atajo-caso especial precisamente para este caso de uso!

Si llama a str.split sin un argumento, se divide en ejecuciones de espacios en blanco en lugar de caracteres individuales. Por lo tanto:

>>> ' '.join("Please \n don't \t hurt \x0b me.".split()) 
"Please don't hurt me." 
+5

Eso es infinitamente mejor que mi solución. También espero volverme inmortal algún día. –

+0

Wow. Esto es increíble. Perfecto para lo que estoy haciendo, ya que son cadenas pequeñas. Me pregunto cómo esto funcionaría en grandes conjuntos de datos sin embargo? Sería genial si alguien sabe cómo funciona intrínsecamente :) – Alex

+0

gracias, no sabía sobre el uso de ningún argumento para las carreras de espacios en blanco. ¡¡Enorme!! – MattoTodd

1

un punto de partida .. (aunque no es más corto que el montaje manual del circo espacio en blanco) ..

>>> from string import whitespace as ws 
>>> import re 

>>> p = re.compile('(%s)' % ('|'.join([c for c in ws]))) 
>>> s = "Please \n don't \t hurt \x0b me." 

>>> p.sub('', s) 
"Pleasedon'thurtme." 

O si desea reducir el espacio en blanco a un máximo de un:

>>> p1 = re.compile('(%s)' % ('|'.join([c for c in ws if not c == ' ']))) 
>>> p2 = re.compile(' +') 
>>> s = "Please \n don't \t hurt \x0b me." 

>>> p2.sub(' ', p1.sub('', s)) 
"Please don't hurt me." 

De la tercera manera, más compacto:

>>> import string 

>>> s = "Please \n don't \t hurt \x0b me." 
>>> s.translate(None, string.whitespace[]) 
"Pleasedon'thurtme." 

>>> s.translate(None, string.whitespace[:5]) 
"Please don't hurt me." 

>>> ' '.join(s.translate(None, string.whitespace[:5]).split()) 
"Please don't hurt me." 
+0

Originalmente tenía esta como la primera respuesta; fue una buena solución y buen uso de la simplicidad de Python :) – Alex

2

Puede utilizar el método de traducción

import string 

s = "Please \n don't \t hurt \x0b me." 
s = s.translate(None, string.whitespace[:-1]) # python 2.6 and up 
s = s.translate(string.maketrans('',''), string.whitespace[:-1]) # python 2.5, dunno further down 
>>> s 
"Please don't hurt me." 

Y a continuación, quitar los espacios en blanco duplicado

s.replace(' ', ' ') 
>>> s 
"Please don't hurt me." 
+0

Parece que no funciona ... ¡sería bueno si lo hiciera! – Alex

+0

ver la edición. también, ¿qué versión de Python estás usando? necesitas 2.6 para que el argumento None funcione. –

+0

Sí, estoy usando 2.5 ... ¿hay alguna alternativa para None? De lo contrario, tendré que usar la otra respuesta ... – Alex

13

Qué le pasa a la clase \s personaje?

>>> import re 

>>> pattern = re.compile(r'\s+') 
>>> re.sub(pattern, ' ', "Please \n don't \t hurt \x0b me.") 
"Please don't hurt me." 
+0

Nada, buena solución. Creo que la opción .join/split es bastante clara, ¿no crees? :) – Alex

+1

De hecho. De hecho, 'timeit' muestra join/split para ser 6 veces más rápido que re.sub() para la cadena dada. – Imran

+0

Supongo que una vez compilado y 'sub' reutilizado varias veces, esto podría ser demasiado rápido –

9

Vamos a hacer algunas suposiciones razonables:

(1) que realmente quiere reemplazar cualquier racha de espacios en blanco con un solo espacio (una carrera es de longitud 1 o mayor).

(2) Le gustaría que el mismo código funcione con cambios mínimos en Python 2.X con objetos Unicode.

(3) Usted no quiere que su código de asumir cosas que no están garantizados en la documentación

(4) ¿Le gustaría el mismo código para trabajar con cambios mínimos con objetos Python 3.X str.

La respuesta seleccionada actualmente tiene estos problemas:

(a) cambios " " * 3-" " * 2 es decir, que elimina espacios duplicados pero no triplicado, cuadruplicado, etc espacios.[Falla requisito 1]

(b) cambia "foo\tbar\tzot" a "foobarzot" [falla requisito 1]

(c) cuando se alimenta un objeto Unicode, obtiene TypeError: translate() takes exactly one argument (2 given) [falla requisito 2]

(d) utiliza string.whitespace[:-1] [falla el requisito 3; El orden de los caracteres en string.whitespace no está garantizado]

(e) utiliza string.whitespace[:-1] [falla el requisito 4; en Python 2.X, string.whitespace es '\t\n\x0b\x0c\r '; en Python 3.x, es '\ t \ n \ r \ x0b \ x0c']

El " ".join(s.split()) respuesta y la respuesta re.sub(r"\s+", " ", s) no tienen estos problemas.

+0

Oye, planteas algunos puntos importantes. Para mí, el '' .join (s.split()) funciona en la prueba "foo \ tbar \ tzot". Quiero decir, la respuesta original funcionó para mí, pero eso es solo porque no estoy esperando cuerdas tan extrañas. Sin embargo, algo que trate con esto sería genial. Acabo de probar el sub con "foo \ tbar \ tzot" y funciona ... así que supongo que estoy eligiendo la versión '' .join (s.split()) debido a su simplicidad y poder trabajar sin importar el módulo re Además, mis conjuntos de datos son pequeños, por lo que no me preocupan los problemas de rendimiento, si es que hay alguno. – Alex

Cuestiones relacionadas