¿Cómo recorto espacios en blanco?

1071

¿Existe una función de Python que recorte espacios en blanco (espacios y tabulaciones) de una cadena?

Ejemplo: \t example string\texample string

Chris
fuente
1
Gracias por el aviso. Descubrí la función de tira antes, pero no parece estar funcionando para mi entrada ..
Chris
1
Igual que: stackoverflow.com/questions/761804/trimming-a-string-in-python (aunque esta pregunta es un poco más clara, en mi humilde opinión). Esto también es casi lo mismo: stackoverflow.com/questions/959215/…
Jonik
66
Los caracteres que Python considera los espacios en blanco se almacenan string.whitespace.
John Fouhy el
2
¿Por "función de tira" quieres decir método de tira? "no parece estar funcionando para mi entrada" Proporcione su código, su entrada y la salida.
S.Lott
55
Posible duplicado de Recortar una cuerda en Python
Breno Baiardi

Respuestas:

1600

Espacio en blanco en ambos lados:

s = "  \t a string example\t  "
s = s.strip()

Espacio en blanco en el lado derecho:

s = s.rstrip()

Espacio en blanco en el lado izquierdo:

s = s.lstrip()

Como señala thedz , puede proporcionar un argumento para quitar caracteres arbitrarios a cualquiera de estas funciones como esta:

s = s.strip(' \t\n\r')

Esto quitará cualquier espacio, \t, \n, o \rpersonajes del lado izquierdo, lado derecho, o ambos lados de la cadena.

Los ejemplos anteriores solo eliminan cadenas de los lados izquierdo y derecho de las cadenas. Si también desea eliminar caracteres del medio de una cadena, intente re.sub:

import re
print re.sub('[\s+]', '', s)

Eso debería imprimir:

astringexample
James Thompson
fuente
18
strip () toma un argumento para decirle qué disparar. Prueba: strip ('\ t \ n \ r')
thedz el
3
Los resultados de los ejemplos deberían ser bastante útiles :)
ton
44
No es necesario enumerar los caracteres de espacio en blanco: docs.python.org/2/library/string.html#string.whitespace
jesuis
3
El último ejemplo es exactamente como usar str.replace(" ",""). No necesita usar re, a menos que tenga más de un espacio, entonces su ejemplo no funciona. []está diseñado para marcar caracteres individuales, no es necesario si está usando solo \s. Utilice uno \s+o [\s]+(innecesario), pero [\s+]no hacer el trabajo, en particular, si desea reemplazar los múltiples espacios con uno solo como convertir "this example" en "this example".
Jorge E. Cardona
3
@ JorgeE.Cardona: algo en lo que estás un poco equivocado \sincluirá pestañas, mientras replace(" ", "")que no lo hará.
ArtOfWarfare
72

El trimmétodo Python se llama strip:

str.strip() #trim
str.lstrip() #ltrim
str.rstrip() #rtrim
gcb
fuente
55
lo cual es fácil de recordar porque s tri p se parece casi a tri m.
isar
22

Para espacios en blanco iniciales y finales:

s = '   foo    \t   '
print s.strip() # prints "foo"

De lo contrario, una expresión regular funciona:

import re
pat = re.compile(r'\s+')
s = '  \t  foo   \t   bar \t  '
print pat.sub('', s) # prints "foobar"
ars
fuente
1
No compiló su expresión regular. Necesitas hacer que seapat = re.compile(r'\s+')
Evan Fosmark
En general, usted quiere sub(" ", s)no ""la tarde se fusionarán las palabras y ya no será capaz de utilizar .split(" ")a tokenize.
user3467349
sería bueno ver el resultado de las printdeclaraciones
Ron Klein
19

También puede usar una función muy simple y básica: str.replace () , funciona con espacios en blanco y pestañas:

>>> whitespaces = "   abcd ef gh ijkl       "
>>> tabs = "        abcde       fgh        ijkl"

>>> print whitespaces.replace(" ", "")
abcdefghijkl
>>> print tabs.replace(" ", "")
abcdefghijkl

Simple y fácil.

Lucas
fuente
2
Pero esto, por desgracia, también elimina el espacio interior, mientras que el ejemplo en la pregunta original deja intactos los espacios interiores.
Brandon Rhodes
12
#how to trim a multi line string or a file

s=""" line one
\tline two\t
line three """

#line1 starts with a space, #2 starts and ends with a tab, #3 ends with a space.

s1=s.splitlines()
print s1
[' line one', '\tline two\t', 'line three ']

print [i.strip() for i in s1]
['line one', 'line two', 'line three']




#more details:

#we could also have used a forloop from the begining:
for line in s.splitlines():
    line=line.strip()
    process(line)

#we could also be reading a file line by line.. e.g. my_file=open(filename), or with open(filename) as myfile:
for line in my_file:
    line=line.strip()
    process(line)

#moot point: note splitlines() removed the newline characters, we can keep them by passing True:
#although split() will then remove them anyway..
s2=s.splitlines(True)
print s2
[' line one\n', '\tline two\t\n', 'line three ']
robert king
fuente
4

Nadie ha publicado aún estas soluciones de expresiones regulares.

Pareo:

>>> import re
>>> p=re.compile('\\s*(.*\\S)?\\s*')

>>> m=p.match('  \t blah ')
>>> m.group(1)
'blah'

>>> m=p.match('  \tbl ah  \t ')
>>> m.group(1)
'bl ah'

>>> m=p.match('  \t  ')
>>> print m.group(1)
None

Buscando (debe manejar el caso de entrada de "solo espacios" de manera diferente):

>>> p1=re.compile('\\S.*\\S')

>>> m=p1.search('  \tblah  \t ')
>>> m.group()
'blah'

>>> m=p1.search('  \tbl ah  \t ')
>>> m.group()
'bl ah'

>>> m=p1.search('  \t  ')
>>> m.group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'

Si lo usa re.sub, puede eliminar los espacios en blanco internos, lo que podría ser indeseable.

usuario1149913
fuente
3

El espacio en blanco incluye espacio, pestañas y CRLF . Entonces, una función de cadena elegante y de una línea que podemos usar es traducir .

' hello apple'.translate(None, ' \n\t\r')

O si quieres ser minucioso

import string
' hello  apple'.translate(None, string.whitespace)
MaK
fuente
3

(re.sub ('+', '', (my_str.replace ('\ n', '')))). strip ()

Esto eliminará todos los espacios no deseados y los caracteres de nueva línea. Espero que esto ayude

import re
my_str = '   a     b \n c   '
formatted_str = (re.sub(' +', ' ',(my_str.replace('\n',' ')))).strip()

Esto resultará:

'a b \ nc' se cambiará a 'ab c'

Safvan CK
fuente
2
    something = "\t  please_     \t remove_  all_    \n\n\n\nwhitespaces\n\t  "

    something = "".join(something.split())

salida:

please_remove_all_whitespaces


Añadiendo el comentario de Le Droid a la respuesta. Para separar con un espacio:

    something = "\t  please     \t remove  all   extra \n\n\n\nwhitespaces\n\t  "
    something = " ".join(something.split())

salida:

elimine todos los espacios en blanco adicionales

pbn
fuente
1
Simple y eficiente. Podría usar "" .join (... para mantener las palabras separadas con un espacio.
Le Droid
1

Si usa Python 3: en su declaración de impresión, termine con sep = "". Eso separará todos los espacios.

EJEMPLO:

txt="potatoes"
print("I love ",txt,"",sep="")

Esto imprimirá: me encantan las papas.

En lugar de: me encantan las papas.

En su caso, dado que intentaría obtener el \ t, haga sep = "\ t"

morgansmnm
fuente
1

Después de haber analizado algunas soluciones aquí con diversos grados de comprensión, me pregunté qué hacer si la cadena estaba separada por comas ...

el problema

Al intentar procesar un csv de información de contacto, necesitaba una solución a este problema: recortar espacios en blanco extraños y algo de basura, pero preservar las comas finales y los espacios en blanco internos. Al trabajar con un campo que contenía notas en los contactos, quería eliminar la basura, dejando las cosas buenas. Recortando toda la puntuación y la paja, no quería perder el espacio en blanco entre las fichas compuestas, ya que no quería reconstruir más tarde.

expresiones regulares y patrones: [\s_]+?\W+

El patrón busca instancias únicas de cualquier carácter de espacio en blanco y el guión bajo ('_') de 1 a un número ilimitado de veces de forma perezosa (tan pocos caracteres como sea posible) [\s_]+?antes de que aparezcan caracteres que no sean palabras de 1 a una cantidad ilimitada de tiempo con esto: \W+(es equivalente a [^a-zA-Z0-9_]). Específicamente, esto encuentra franjas de espacios en blanco: caracteres nulos (\ 0), tabulaciones (\ t), líneas nuevas (\ n), avance (\ f), retornos de carro (\ r).

Veo la ventaja de esto como doble:

  1. que no elimina el espacio en blanco entre las palabras / fichas completas que quizás desee mantener juntas;

  2. El método de cadena incorporado de Python strip()no se ocupa dentro de la cadena, solo los extremos izquierdo y derecho, y el argumento predeterminado son caracteres nulos (vea el ejemplo a continuación: varias líneas nuevas están en el texto y strip()no las elimina todas mientras que el patrón de expresiones regulares lo hace) .text.strip(' \n\t\r')

Esto va más allá de la pregunta de los OP, pero creo que hay muchos casos en los que podríamos tener instancias patológicas extrañas dentro de los datos de texto, como lo hice yo (de alguna manera, los caracteres de escape terminaron en parte del texto). Además, en cadenas de tipo lista, no queremos eliminar el delimitador a menos que el delimitador separe dos caracteres de espacio en blanco o algún carácter que no sea de palabra, como '-,' o '-, ,,,'.

NB: No estoy hablando del delimitador del CSV en sí. Solo de instancias dentro del CSV donde los datos son como una lista, es decir, es una cadena cs de subcadenas.

Revelación completa: solo he estado manipulando texto durante aproximadamente un mes, y regexé solo las últimas dos semanas, así que estoy seguro de que me faltan algunos matices. Dicho esto, para colecciones más pequeñas de cadenas (las mías están en un marco de datos de 12,000 filas y 40 columnas impares), como paso final después de un pase para la eliminación de caracteres extraños, esto funciona excepcionalmente bien, especialmente si introduce un espacio en blanco adicional donde desea separar el texto unido por un carácter que no es de palabra, pero no desea agregar espacios en blanco donde antes no había ninguno.

Un ejemplo:

import re


text = "\"portfolio, derp, hello-world, hello-, -world, founders, mentors, :, ?, %, ,>, , ffib, biff, 1, 12.18.02, 12,  2013, 9874890288, .., ..., ...., , ff, series a, exit, general mailing, fr, , , ,, co founder, pitch_at_palace, ba, _slkdjfl_bf, sdf_jlk, )_(, [email protected], ,dd invites,subscribed,, master, , , ,  dd invites,subscribed, , , , \r, , \0, ff dd \n invites, subscribed, , ,  , , alumni spring 2012 deck: https: www.dropbox.com s, \n i69rpofhfsp9t7c practice 20ignition - 20june \t\n .2134.pdf 2109                                                 \n\n\n\nklkjsdf\""

print(f"Here is the text as formatted:\n{text}\n")
print()
print("Trimming both the whitespaces and the non-word characters that follow them.")
print()
trim_ws_punctn = re.compile(r'[\s_]+?\W+')
clean_text = trim_ws_punctn.sub(' ', text)
print(clean_text)
print()
print("what about 'strip()'?")
print(f"Here is the text, formatted as is:\n{text}\n")
clean_text = text.strip(' \n\t\r')  # strip out whitespace?
print()
print(f"Here is the text, formatted as is:\n{clean_text}\n")

print()
print("Are 'text' and 'clean_text' unchanged?")
print(clean_text == text)

Esto produce:

Here is the text as formatted:

"portfolio, derp, hello-world, hello-, -world, founders, mentors, :, ?, %, ,>, , ffib, biff, 1, 12.18.02, 12,  2013, 9874890288, .., ..., ...., , ff, series a, exit, general mailing, fr, , , ,, co founder, pitch_at_palace, ba, _slkdjfl_bf, sdf_jlk, )_(, [email protected], ,dd invites,subscribed,, master, , , ,  dd invites,subscribed, ,, , , ff dd 
 invites, subscribed, , ,  , , alumni spring 2012 deck: https: www.dropbox.com s, 
 i69rpofhfsp9t7c practice 20ignition - 20june 
 .2134.pdf 2109                                                 



klkjsdf" 

using regex to trim both the whitespaces and the non-word characters that follow them.

"portfolio, derp, hello-world, hello-, world, founders, mentors, ffib, biff, 1, 12.18.02, 12, 2013, 9874890288, ff, series a, exit, general mailing, fr, co founder, pitch_at_palace, ba, _slkdjfl_bf, sdf_jlk,  [email protected], dd invites,subscribed,, master, dd invites,subscribed, ff dd invites, subscribed, alumni spring 2012 deck: https: www.dropbox.com s, i69rpofhfsp9t7c practice 20ignition 20june 2134.pdf 2109 klkjsdf"

Very nice.
What about 'strip()'?

Here is the text, formatted as is:

"portfolio, derp, hello-world, hello-, -world, founders, mentors, :, ?, %, ,>, , ffib, biff, 1, 12.18.02, 12,  2013, 9874890288, .., ..., ...., , ff, series a, exit, general mailing, fr, , , ,, co founder, pitch_at_palace, ba, _slkdjfl_bf, sdf_jlk, )_(, [email protected], ,dd invites,subscribed,, master, , , ,  dd invites,subscribed, ,, , , ff dd 
 invites, subscribed, , ,  , , alumni spring 2012 deck: https: www.dropbox.com s, 
 i69rpofhfsp9t7c practice 20ignition - 20june 
 .2134.pdf 2109                                                 



klkjsdf"


Here is the text, after stipping with 'strip':


"portfolio, derp, hello-world, hello-, -world, founders, mentors, :, ?, %, ,>, , ffib, biff, 1, 12.18.02, 12,  2013, 9874890288, .., ..., ...., , ff, series a, exit, general mailing, fr, , , ,, co founder, pitch_at_palace, ba, _slkdjfl_bf, sdf_jlk, )_(, [email protected], ,dd invites,subscribed,, master, , , ,  dd invites,subscribed, ,, , , ff dd 
 invites, subscribed, , ,  , , alumni spring 2012 deck: https: www.dropbox.com s, 
 i69rpofhfsp9t7c practice 20ignition - 20june 
 .2134.pdf 2109                                                 



klkjsdf"
Are 'text' and 'clean_text' unchanged? 'True'

Entonces strip elimina un espacio en blanco de a la vez. Entonces, en el caso de los OP, strip()está bien. pero si las cosas se vuelven más complejas, la expresión regular y un patrón similar pueden ser de algún valor para configuraciones más generales.

verlo en acción

joshua fiddler
fuente
0

intenta traducir

>>> import string
>>> print '\t\r\n  hello \r\n world \t\r\n'

  hello 
 world  
>>> tr = string.maketrans(string.whitespace, ' '*len(string.whitespace))
>>> '\t\r\n  hello \r\n world \t\r\n'.translate(tr)
'     hello    world    '
>>> '\t\r\n  hello \r\n world \t\r\n'.translate(tr).replace(' ', '')
'helloworld'
海洋 顶端
fuente
0

Si desea recortar el espacio en blanco solo al principio y al final de la cadena, puede hacer algo como esto:

some_string = "    Hello,    world!\n    "
new_string = some_string.strip()
# new_string is now "Hello,    world!"

Esto funciona de manera muy similar al método QString :: trimmed () de Qt, ya que elimina los espacios en blanco iniciales y finales, dejando solo los espacios en blanco internos.

Pero si desea algo como el método QString :: simplified () de Qt que no solo elimina los espacios en blanco iniciales y finales, sino que también "separa" todos los espacios en blanco internos consecutivos a un carácter de espacio, puede usar una combinación de .split()y " ".join, de esta manera:

some_string = "\t    Hello,  \n\t  world!\n    "
new_string = " ".join(some_string.split())
# new_string is now "Hello, world!"

En este último ejemplo, cada secuencia de espacios en blanco internos se reemplaza con un solo espacio, mientras se recorta el espacio en blanco del inicio y el final de la cadena.

JL
fuente
-1

En general, estoy usando el siguiente método:

>>> myStr = "Hi\n Stack Over \r flow!"
>>> charList = [u"\u005Cn",u"\u005Cr",u"\u005Ct"]
>>> import re
>>> for i in charList:
        myStr = re.sub(i, r"", myStr)

>>> myStr
'Hi Stack Over  flow'

Nota: Esto es solo para eliminar "\ n", "\ r" y "\ t" solamente. No elimina espacios adicionales.

Mayur Koshti
fuente
-2

para eliminar espacios en blanco del medio de la cadena

$p = "ATGCGAC ACGATCGACC";
$p =~ s/\s//g;
print $p;

salida:

ATGCGACACGATCGACC
Maestro roshi
fuente
1
esta pregunta es sobre python, no Javascript o perl
phuclv
-17

Esto eliminará todos los espacios en blanco y las nuevas líneas del principio y el final de una cadena:

>>> s = "  \n\t  \n   some \n text \n     "
>>> re.sub("^\s+|\s+$", "", s)
>>> "some \n text"
Rafe
fuente
8
¿Por qué usar una expresión regular cuando s.strip()hace exactamente esto?
Ned Batchelder
1
s.strip()solo maneja el espacio en blanco inicial , pero no el espacio en blanco "descubierto" después de eliminar otros caracteres no deseados. Tenga en cuenta que esto eliminará incluso el espacio en blanco después del liderato final\n
Rafe
Alguien rechazó esta respuesta pero no explicó por qué es defectuosa. Vergüenza (@NedBatchelder si el voto negativo fue usted, por favor invierta mientras explicaba su pregunta y no mencionó nada realmente roto con mi respuesta)
Rafe
10
Rafe, es posible que desee verificar dos s.strip()veces : produce exactamente el mismo resultado que su expresión regular.
Ned Batchelder
3
@Rafe, lo estás confundiendo con recortar. Strip realiza las operaciones requeridas.
iMitwe