Come posso tagliare gli spazi bianchi?


1071

Esiste una funzione Python che taglierà gli spazi bianchi (spazi e tabulazioni) da una stringa?

Esempio: \t example string\texample string


1
Grazie per il testa a testa. Avevo scoperto la funzione strip prima, ma non sembra funzionare per il mio input ..
Chris,

1
Come per stackoverflow.com/questions/761804/trimming-a-string-in-python (anche se questa domanda è leggermente più chiara, IMHO). Questo è anche quasi lo stesso: stackoverflow.com/questions/959215/...
Jonik

6
I caratteri che Python considera gli spazi bianchi sono memorizzati string.whitespace.
John Fouhy,

2
Con "funzione strip" intendi il metodo strip? "non sembra funzionare per il mio input" Fornire il codice, l'input e l'output.
S. Lott,

Risposte:


1600

Spazio bianco su entrambi i lati:

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

Spazio bianco sul lato destro:

s = s.rstrip()

Spazio bianco sul lato sinistro:

s = s.lstrip()

Come sottolinea thedz , puoi fornire un argomento per eliminare caratteri arbitrari a una di queste funzioni come questa:

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

Questo eliminerà qualsiasi spazio, \t, \n, o \rcaratteri dal lato sinistro, lato destro, o entrambe le facce della stringa.

Gli esempi sopra rimuovono solo le stringhe dai lati sinistro e destro delle stringhe. Se vuoi rimuovere anche i caratteri dal centro di una stringa, prova re.sub:

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

Quello dovrebbe stampare:

astringexample

18
strip () accetta un argomento per dirgli cosa inciampare. Prova: strip ('\ t \ n \ r')
giovedì

3
I risultati degli esempi dovrebbero essere abbastanza utili :)
ton

4
Non è necessario elencare i caratteri degli spazi bianchi: docs.python.org/2/library/string.html#string.whitespace
jesuis

3
L'ultimo esempio è esattamente come usando str.replace(" ",""). Non hai bisogno di usare re, a meno che tu non abbia più di uno spazio, il tuo esempio non funziona. []è progettato per contrassegnare singoli caratteri, non è necessario se si utilizza solo \s. Utilizzare uno \s+o [\s]+(non necessario) ma [\s+]non fa il lavoro, in particolare se si desidera sostituire più spazi con uno singolo come trasformarsi "this example" in "this example".
Jorge E. Cardona,

3
@ JorgeE.Cardona - Una cosa di cui ti sbagli leggermente - \sincluderà le schede mentre replace(" ", "")no.
ArtOfWarfare il

72

Il trimmetodo Python si chiama strip:

str.strip() #trim
str.lstrip() #ltrim
str.rstrip() #rtrim

5
che è facile da ricordare perché s tri p sembra quasi tri .
Isar,

22

Per spazi bianchi iniziali e finali:

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

Altrimenti, funziona un'espressione regolare:

import re
pat = re.compile(r'\s+')
s = '  \t  foo   \t   bar \t  '
print pat.sub('', s) # prints "foobar"

1
Non hai compilato la tua regex. Devi farlopat = re.compile(r'\s+')
Evan Fosmark il

In genere sub(" ", s)non si desidera che ""successivamente le parole vengano .split(" ")unite e non sarà più possibile utilizzare per tokenizzare.
user3467349,

sarebbe bello vedere l'output delle printdichiarazioni
Ron Klein,

19

Puoi anche usare una funzione molto semplice e di base: str.replace () , funziona con gli spazi bianchi e le schede:

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

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

Semplice e facile.


2
Ma questo, purtroppo, rimuove anche lo spazio interno, mentre l'esempio nella domanda originale lascia intatti gli spazi interni.
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 ']

4

Nessuno ha ancora pubblicato queste soluzioni regex.

Corrispondenza:

>>> 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

Ricerca (devi gestire il caso di input "solo spazi" in modo diverso):

>>> 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'

Se lo usi re.sub, puoi rimuovere gli spazi bianchi interni, il che potrebbe essere indesiderabile.


3

Lo spazio bianco include spazio, tabulazioni e CRLF . Quindi una funzione di stringa elegante e di una riga che possiamo usare è tradurre .

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

O se vuoi essere accurato

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

3

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

Ciò rimuoverà tutti gli spazi indesiderati e i caratteri di nuova riga. Spero che questo aiuto

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

Ciò comporterà:

"a b \ nc" verrà modificato in "ab c"


2
    something = "\t  please_     \t remove_  all_    \n\n\n\nwhitespaces\n\t  "

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

produzione:

please_remove_all_whitespaces


Aggiungendo il commento di Le Droid alla risposta. Per separare con uno spazio:

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

produzione:

rimuovere tutti gli spazi bianchi extra


1
Semplice ed efficiente Potrebbe usare "" .join (... per mantenere le parole separate da uno spazio.
Le Droid

1

Se si utilizza Python 3: nell'istruzione print, finire con sep = "". Ciò separerà tutti gli spazi.

ESEMPIO:

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

Questo stamperà: amo le patate.

Invece di: adoro le patate.

Nel tuo caso, dal momento che dovresti provare a cavalcare il \ t, fai sep = "\ t"


1

Dopo aver esaminato alcune soluzioni qui con vari gradi di comprensione, mi chiedevo cosa fare se la stringa fosse separata da virgola ...

il problema

Durante il tentativo di elaborare un csv di informazioni di contatto, avevo bisogno di una soluzione a questo problema: tagliare gli spazi bianchi estranei e alcuni junk, ma preservare le virgole finali e gli spazi bianchi interni. Lavorando con un campo contenente note sui contatti, volevo rimuovere la spazzatura, lasciando le cose buone. Eliminando tutta la punteggiatura e la pula, non volevo perdere lo spazio bianco tra i token composti poiché non volevo ricostruire in seguito.

regex e modelli: [\s_]+?\W+

Il modello cerca singole istanze di qualsiasi carattere di spazio bianco e il trattino basso ('_') da 1 a un numero illimitato di volte pigramente (il minor numero possibile di caratteri) con [\s_]+?quello che precede i caratteri non di parole che si verificano da 1 a un numero illimitato di tempo con questo: \W+(è equivalente a [^a-zA-Z0-9_]). Nello specifico, questo trova strisce di spazi bianchi: caratteri null (\ 0), tabs (\ t), newline (\ n), feed-forward (\ f), ritorni a capo (\ r).

Vedo il vantaggio di questo come duplice:

  1. che non rimuove gli spazi bianchi tra le parole / i token completi che potresti voler tenere insieme;

  2. Il metodo di stringa incorporato di Python strip()non si occupa all'interno della stringa, ma solo le estremità sinistra e destra e arg predefinito è costituito da caratteri null (vedere l'esempio seguente: nel testo sono presenti diverse nuove righe e strip()non le rimuove tutte mentre lo fa il modello regex) .text.strip(' \n\t\r')

Questo va oltre la domanda dei PO, ma penso che ci siano molti casi in cui potremmo avere casi strani e patologici all'interno dei dati di testo, come ho fatto io (alcuni di come i caratteri di fuga sono finiti in alcuni dei testi). Inoltre, nelle stringhe simili a elenchi, non vogliamo eliminare il delimitatore a meno che il delimitatore non separi due caratteri di spazi bianchi o alcuni caratteri non di parole, come '-,' o '-, ,,,'.

NB: Non si parla del delimitatore del CSV stesso. Solo delle istanze all'interno del CSV in cui i dati sono simili a elenchi, ovvero una stringa cs di sottostringhe.

Divulgazione completa: ho manipolato il testo solo per circa un mese e ho ripreso solo le ultime due settimane, quindi sono sicuro che ci sono alcune sfumature che mi mancano. Detto questo, per le raccolte di stringhe più piccole (le mie sono in un frame di dati di 12.000 righe e 40 colonne dispari), come passaggio finale dopo un passaggio per la rimozione di caratteri estranei, questo funziona eccezionalmente bene, specialmente se si introduce uno spazio bianco aggiuntivo in cui si desidera separare il testo unito da un carattere non di parole, ma non desidera aggiungere spazi bianchi dove prima non c'era nessuno.

Un esempio:

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, )_(, jim.somedude@blahblah.com, ,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)

Questo 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, )_(, jim.somedude@blahblah.com, ,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,  jim.somedude@blahblah.com, 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, )_(, jim.somedude@blahblah.com, ,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, )_(, jim.somedude@blahblah.com, ,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'

Quindi strip rimuove uno spazio bianco alla volta. Quindi, nel caso dei PO, strip()va bene. ma se le cose diventano più complesse, regex e uno schema simile potrebbero essere di qualche valore per impostazioni più generali.

vederlo in azione


0

prova a tradurre

>>> 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'

0

Se vuoi tagliare lo spazio vuoto solo all'inizio e alla fine della stringa, puoi fare qualcosa del genere:

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

Funziona in modo molto simile al metodo QString :: trimmed () di Qt, in quanto rimuove gli spazi bianchi iniziali e finali, lasciando solo gli spazi bianchi interni.

Ma se desideri qualcosa come il metodo Qttring :: simplified () di Qt che non solo rimuove gli spazi bianchi iniziali e finali, ma anche "schiaccia" tutti gli spazi bianchi interni consecutivi su un carattere spaziale, puoi usare una combinazione di .split()e " ".join, in questo modo:

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

In questo ultimo esempio, ogni sequenza di spazi bianchi interni è stata sostituita da un singolo spazio, pur tagliando lo spazio bianco all'inizio e alla fine della stringa.


-1

In generale, sto usando il seguente metodo:

>>> 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: serve solo per rimuovere "\ n", "\ r" e "\ t". Non rimuove gli spazi extra.


-2

per rimuovere gli spazi bianchi dal centro della stringa

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

produzione:

ATGCGACACGATCGACC

1
questa domanda riguarda python, non Javascript o perl
phuclv,

-17

Ciò rimuoverà tutti gli spazi bianchi e le nuove righe sia dall'inizio che dalla fine di una stringa:

>>> s = "  \n\t  \n   some \n text \n     "
>>> re.sub("^\s+|\s+$", "", s)
>>> "some \n text"

8
Perché usare un regex quando s.strip()fa esattamente questo?
Ned Batchelder,

1
s.strip()gestisce solo lo spazio bianco iniziale , ma non gli spazi bianchi "scoperti" dopo aver rimosso altri caratteri indesiderati. Nota che questo rimuoverà anche gli spazi bianchi dopo il comando finale\n
Rafe

Qualcuno ha votato in negativo questa risposta, ma non ha spiegato perché sia ​​difettoso. Peccato per te (@NedBatchelder se il voto negativo è stato per favore, al contrario, ho spiegato la tua domanda e non hai menzionato nulla di veramente rotto con la mia risposta)
Rafe

10
Rafe, potresti voler ricontrollare: s.strip()produce esattamente lo stesso risultato del tuo regex.
Ned Batchelder,

3
@Rafe, lo stai confondendo con il trim. Strip esegue le operazioni richieste.
iMitwe,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.