Como aparar espaços em branco?


1071

Existe uma função Python que apara os espaços em branco (espaços e tabulações) de uma string?

Exemplo: \t example string\texample string


1
Obrigado pela atenção. Eu tinha descoberto a função tira mais cedo, mas não parece estar a trabalhar para a minha entrada ..
Chris

1
O mesmo que: stackoverflow.com/questions/761804/trimming-a-string-in-python (embora essa pergunta seja um pouco mais clara, IMHO). Isso também é quase o mesmo: stackoverflow.com/questions/959215/…
Jonik

6
Os caracteres que o python considera que os espaços em branco estão armazenados string.whitespace.
31410 John Fouhy

2
Por "função de tira", você quer dizer método de tira? "parece não estar funcionando para minha entrada" Por favor, forneça seu código, sua entrada e a saída.
315/09 S.Lott

5
Possível duplicado da Corte uma string em Python
Breno Baiardi

Respostas:


1600

Espaço em branco em ambos os lados:

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

Espaço em branco no lado direito:

s = s.rstrip()

Espaço em branco no lado esquerdo:

s = s.lstrip()

Como thedz aponta, você pode fornecer um argumento para remover caracteres arbitrários para qualquer uma dessas funções como esta:

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

Isto irá retirar qualquer espaço, \t, \n, ou \rpersonagens de lado esquerdo, do lado direito, ou ambos os lados da corda.

Os exemplos acima removem apenas as cordas dos lados esquerdo e direito das cordas. Se você também deseja remover caracteres do meio de uma string, tente re.sub:

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

Isso deve ser impresso:

astringexample

18
strip () leva um argumento para dizer o que tropeçar. Tente: strip ('\ t \ n \ r')
thedz

3
Resultados para os exemplos devem ser bastante útil :)
ton

4
Não há necessidade de listar os caracteres de espaço em branco: docs.python.org/2/library/string.html#string.whitespace
jesuis

3
O último exemplo é exatamente como o uso str.replace(" ",""). Você não precisa usar re, a menos que tenha mais de um espaço, seu exemplo não funcionará. []foi projetado para marcar caracteres únicos, não é necessário se você estiver usando apenas \s. Use um \s+ou [\s]+(desnecessário), mas [\s+]não fazer o trabalho, em especial, se você deseja substituir os espaços múltiplos com um único como transformar "this example" em "this example".
Jorge E. Cardona

3
@ JorgeE.Cardona - Uma coisa sobre a qual você está meio enganado - \sincluirá guias enquanto replace(" ", "")não estiver .
ArtOfWarfare 30/03

72

O trimmétodo Python é chamado strip:

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

5
o que é fácil de lembrar porque s tri p parece quase tri m.
Isar

22

Para espaços em branco à esquerda e à direita:

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

Caso contrário, uma expressão regular funcionará:

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

1
Você não compilou seu regex. Você precisa fazer com que sejapat = re.compile(r'\s+')
Evan Fosmark

Você geralmente quer sub(" ", s)não ""o mais tarde irá mesclar as palavras e você já não vai ser capaz de usar .split(" ")a tokenizar.
user3467349

seria bom para ver a saída das printdeclarações
Ron Klein

19

Você também pode usar uma função muito simples e básica: str.replace () , trabalha com os espaços em branco e as guias:

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

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

Simples e fácil.


2
Mas isso, infelizmente, também remove o espaço interior, enquanto o exemplo na pergunta original deixa os espaços interiores intocados.
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

Ninguém postou essas soluções de regex ainda.

Coincidindo:

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

Pesquisando (você precisa manipular o caso de entrada "apenas espaços" de maneira 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'

Se você usar re.sub, poderá remover o espaço em branco interno, o que pode ser indesejável.


3

Espaço em branco inclui espaço, guias e CRLF . Portanto, uma função de string elegante e de uma linha que podemos usar é traduzir .

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

OU se você quiser ser completo

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

3

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

Isso removerá todos os espaços indesejados e caracteres de nova linha. Espero que esta ajuda

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

Isso resultará em:

'a b \ nc' será alterado para 'ab c'


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

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

resultado:

please_remove_all_whitespaces


Adicionando o comentário de Le Droid à resposta. Para separar com um espaço:

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

resultado:

remova todos os espaços em branco extras


1
Simples e eficiente. Poderia usar "" .join (... para manter as palavras separadas por um espaço.
Le Droid

1

Se você estiver usando o Python 3: Na sua declaração de impressão, termine com sep = "". Isso separará todos os espaços.

EXEMPLO:

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

Isto irá imprimir: eu amo batatas.

Em vez de: eu amo batatas.

No seu caso, como você tentaria pegar o \ t, faça sep = "\ t"


1

Tendo analisado várias soluções aqui com vários graus de entendimento, me perguntei o que fazer se a string fosse separada por vírgula ...

o problema

Ao tentar processar um CSV de informações de contato, eu precisava de uma solução para este problema: aparar espaços em branco externos e alguns itens indesejados, mas preservar vírgulas finais e espaços em branco internos. Trabalhando com um campo contendo anotações nos contatos, eu queria remover o lixo, deixando as coisas boas. Aparando toda a pontuação e o joio, eu não queria perder o espaço em branco entre os tokens compostos, pois não queria reconstruir mais tarde.

regex e padrões: [\s_]+?\W+

O padrão procura por instâncias únicas de qualquer caractere de espaço em branco e o sublinhado ('_') de 1 a um número ilimitado de vezes preguiçosamente (o mínimo de caracteres possível) com [\s_]+?os caracteres anteriores a não-palavra que ocorrem de 1 a uma quantidade ilimitada de caracteres. tempo com isso: \W+(é equivalente a [^a-zA-Z0-9_]). Especificamente, isso encontra faixas de espaço em branco: caracteres nulos (\ 0), guias (\ t), novas linhas (\ n), feed-forward (\ f), retornos de carro (\ r).

Vejo a vantagem disso como dupla:

  1. que não remove espaços em branco entre as palavras / tokens completos que você pode querer manter juntos;

  2. O método string incorporado do Python strip()não lida dentro da string, apenas as extremidades esquerda e direita, e arg padrão são caracteres nulos (veja o exemplo abaixo: várias novas linhas estão no texto e strip()não as removem todas enquanto o padrão regex) .text.strip(' \n\t\r')

Isso vai além da questão dos OPs, mas acho que há muitos casos em que podemos ter instâncias patológicas estranhas nos dados de texto, como eu fiz (um pouco como os caracteres de escape terminaram em alguns textos). Além disso, em seqüências de caracteres do tipo lista, não queremos eliminar o delimitador, a menos que o delimitador separe dois caracteres de espaço em branco ou algum caractere que não seja da palavra, como '-,' ou '-, ,,,'.

NB: Sem falar no delimitador do próprio CSV. Somente instâncias no CSV em que os dados são do tipo lista, ou seja, são uma sequência de substrings cs.

Divulgação completa: só manipulo o texto há cerca de um mês e regex apenas nas últimas duas semanas, por isso tenho certeza de que algumas nuances estão faltando. Dito isto, para coleções menores de seqüências de caracteres (as minhas estão em um quadro de dados de 12.000 linhas e 40 colunas ímpares), como uma etapa final após um passo para remover caracteres estranhos, isso funciona excepcionalmente bem, especialmente se você introduzir algum espaço em branco adicional em que deseja separar o texto unido por um caractere que não seja uma palavra, mas não deseja adicionar espaços em branco onde não havia antes.

Um exemplo:

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)

Isso gera:

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'

Portanto, tira remove um espaço em branco de cada vez. Portanto, no caso dos OPs, tudo strip()bem. mas se as coisas ficarem mais complexas, regex e um padrão semelhante podem ter algum valor para configurações mais gerais.

vê-lo em ação


0

tente traduzir

>>> 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 você deseja cortar o espaço em branco apenas no início e no final da string, pode fazer algo assim:

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

Isso funciona muito como o método QString :: trimmed () do Qt, na medida em que remove os espaços em branco iniciais e finais, deixando apenas os espaços internos em branco.

Mas se você quiser algo como o método QString :: simplified () do Qt, que não apenas remove os espaços em branco iniciais e finais, mas também "esmaga" todos os espaços em branco internos consecutivos em um caractere de espaço, você pode usar uma combinação de , .split()e " ".joinassim:

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

Neste último exemplo, cada sequência de espaço em branco interno foi substituída por um único espaço, enquanto ainda aparava o espaço em branco no início e no final da string.


-1

Geralmente, estou usando o seguinte 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: Isso é apenas para remover apenas "\ n", "\ r" e "\ t". Não remove espaços extras.


-2

para remover espaços em branco do meio da string

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

resultado:

ATGCGACACGATCGACC

1
esta pergunta é sobre python, não Javascript ou perl
phuclv

-17

Isso removerá todos os espaços em branco e novas linhas do início e do fim de uma string:

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

8
Por que usar uma regex quando s.strip()faz exatamente isso?
Ned Batchelder

1
s.strip()lida apenas com o espaço em branco inicial , mas não com o espaço em branco "descoberto" após remover outros caracteres indesejados. Note que isto irá remover até mesmo o espaço em branco após o líder finais\n
Rafe

Alguém votou negativamente nesta resposta, mas não explicou por que ela é falha. Que vergonha (@NedBatchelder se a votação para baixo foi-lhe agradar reversa como expliquei a sua pergunta e você não mencionou nada realmente quebrado com a minha resposta)
Rafe

10
Rafe, convém verificar duas vezes: s.strip()produz exatamente o mesmo resultado que o seu regex.
Ned Batchelder

3
@ Rafe, você está confundindo com guarnição. Strip faz as operações necessárias.
IMitwe
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.