Comment découper les espaces?

1072

Existe-t-il une fonction Python qui supprimera les espaces (espaces et tabulations) d'une chaîne?

Exemple: \t example string\texample string

Chris
la source
1
Merci pour l'information. J'avais découvert la fonction de bande plus tôt, mais cela ne semble pas fonctionner pour mon entrée ..
Chris
1
Identique à: stackoverflow.com/questions/761804/trimming-a-string-in-python (même si cette question est légèrement plus claire, à mon humble avis). C'est aussi presque le même: stackoverflow.com/questions/959215/…
Jonik
6
Les caractères que python considère comme des espaces sont stockés dans string.whitespace.
John Fouhy
2
Par «fonction de bande», vous voulez dire la méthode de bande? "cela ne semble pas fonctionner pour mon entrée" Veuillez fournir votre code, votre entrée et la sortie.
S.Lott
5
Duplicata possible d' une coupe de chaîne en Python
Breno Baiardi

Réponses:

1600

Espace des deux côtés:

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

Espace sur le côté droit:

s = s.rstrip()

Espace sur le côté gauche:

s = s.lstrip()

Comme le souligne thedz , vous pouvez fournir un argument pour supprimer des caractères arbitraires à l'une de ces fonctions comme ceci:

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

Cela bande d'espace, \t, \n, ou \rcaractères à partir du côté gauche, à droite ou des deux côtés de la chaîne.

Les exemples ci-dessus suppriment uniquement les chaînes des côtés gauche et droit des chaînes. Si vous souhaitez également supprimer des caractères au milieu d'une chaîne, essayez re.sub:

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

Cela devrait imprimer:

astringexample
James Thompson
la source
18
strip () prend un argument pour lui dire quoi trébucher. Essayez: strip ('\ t \ n \ r')
thedz
3
Les résultats des exemples devraient être très utiles :)
ton
4
Pas besoin de lister les espaces: docs.python.org/2/library/string.html#string.whitespace
jesuis
3
Le dernier exemple est exactement comme l'utilisation str.replace(" ",""). Vous n'avez pas besoin d'utiliser re, sauf si vous avez plus d'un espace, alors votre exemple ne fonctionne pas. []est conçu pour marquer des caractères uniques, il n'est pas nécessaire si vous utilisez uniquement \s. Utilisez soit \s+ou [\s]+(inutile) mais [\s+]ne fait pas le travail, en particulier si vous souhaitez remplacer les multiples espaces par un seul comme transformer "this example" en "this example".
Jorge E. Cardona
3
@ JorgeE.Cardona - Une chose sur laquelle vous vous trompez un peu - \sinclura des onglets alors que replace(" ", "")non.
ArtOfWarfare
72

La trimméthode Python est appelée strip:

str.strip() #trim
str.lstrip() #ltrim
str.rstrip() #rtrim
gcb
la source
5
ce qui est facile à retenir car s tri p ressemble presque à tri m.
isar
22

Pour les espaces blancs de début et de fin:

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

Sinon, une expression régulière fonctionne:

import re
pat = re.compile(r'\s+')
s = '  \t  foo   \t   bar \t  '
print pat.sub('', s) # prints "foobar"
ars
la source
1
Vous n'avez pas compilé votre expression régulière. Vous devez le faire êtrepat = re.compile(r'\s+')
Evan Fosmark
Vous ne souhaiterez généralement sub(" ", s)pas que ""le plus tard fusionne les mots et vous ne pourrez plus utiliser la .split(" ")tokenisation.
user3467349
ce serait bien de voir la sortie des printdéclarations
Ron Klein
19

Vous pouvez également utiliser une fonction très simple et basique: str.replace () , fonctionne avec les espaces et les onglets:

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

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

Simple et facile.

Lucas
la source
2
Mais cela, hélas, supprime également l'espace intérieur, tandis que l'exemple de la question d'origine laisse les espaces intérieurs intacts.
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
la source
4

Personne n'a encore publié ces solutions regex.

Correspondant à:

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

Recherche (vous devez gérer différemment le cas de saisie "uniquement les espaces"):

>>> 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 vous utilisez re.sub, vous pouvez supprimer les espaces intérieurs, ce qui pourrait être indésirable.

user1149913
la source
3

L' espace comprend l' espace, les tabulations et le CRLF . Donc, une fonction de chaîne élégante et à une ligne que nous pouvons utiliser est la traduction .

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

OU si vous voulez être minutieux

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

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

Cela supprimera tous les espaces indésirables et les caractères de nouvelle ligne. J'espère que cette aide

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

Il en résultera:

'a b \ nc' sera changé en 'ab c'

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

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

production:

please_remove_all_whitespaces


Ajout du commentaire de Le Droid à la réponse. Pour séparer avec un espace:

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

production:

veuillez supprimer tous les espaces blancs supplémentaires

pbn
la source
1
Simple et efficace. Pourrait utiliser "" .join (... pour séparer les mots par un espace.
Le Droid
1

Si vous utilisez Python 3: Dans votre instruction d'impression, terminez par sep = "". Cela séparera tous les espaces.

EXEMPLE:

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

Cela imprimera: J'adore les pommes de terre.

Au lieu de: j'aime les pommes de terre.

Dans votre cas, puisque vous tenteriez de vous débarrasser du \ t, faites sep = "\ t"

morgansmnm
la source
1

Après avoir examiné plusieurs solutions ici avec différents degrés de compréhension, je me suis demandé quoi faire si la chaîne était séparée par des virgules ...

le problème

En essayant de traiter une csv d'informations de contact, j'avais besoin d'une solution à ce problème: couper les espaces étrangers et certains déchets, mais conserver les virgules de fin et les espaces internes. En travaillant avec un champ contenant des notes sur les contacts, je voulais enlever les ordures, laissant les bonnes choses. En supprimant toute la ponctuation et la balle, je ne voulais pas perdre l'espace blanc entre les jetons composés car je ne voulais pas reconstruire plus tard.

expression régulière et modèles: [\s_]+?\W+

Le modèle recherche des instances uniques de n'importe quel caractère d'espacement et le trait de soulignement ('_') de 1 à un nombre illimité de fois paresseusement (aussi peu de caractères que possible), [\s_]+?avant les caractères non verbaux se produisant de 1 à une quantité illimitée de temps avec ceci: \W+(est équivalent à [^a-zA-Z0-9_]). Plus précisément, cela trouve des étendues d'espaces: caractères nuls (\ 0), tabulations (\ t), nouvelles lignes (\ n), feed-forward (\ f), retours chariot (\ r).

Je vois l'avantage à cela comme double:

  1. qu'il ne supprime pas les espaces entre les mots / jetons complets que vous voudrez peut-être garder ensemble;

  2. La méthode de chaîne intégrée de Python strip()ne traite pas à l'intérieur de la chaîne, juste les extrémités gauche et droite, et l'argument par défaut est des caractères nuls (voir l'exemple ci-dessous: plusieurs sauts de ligne sont dans le texte, et strip()ne les suppriment pas tous alors que le modèle regex le fait) .text.strip(' \n\t\r')

Cela va au-delà de la question des PO, mais je pense qu'il y a beaucoup de cas où nous pourrions avoir des instances étranges et pathologiques dans les données de texte, comme je l'ai fait (comment les caractères d'échappement se sont retrouvés dans une partie du texte). De plus, dans les chaînes de type liste, nous ne voulons pas éliminer le délimiteur à moins que le délimiteur ne sépare deux espaces ou un caractère autre qu'un mot, comme '-,' ou '-, ,,,'.

NB: Ne parle pas du délimiteur du CSV lui-même. Uniquement les instances du CSV où les données sont de type liste, c'est-à-dire une chaîne cs de sous-chaînes.

Divulgation complète: je ne manipule du texte que depuis environ un mois, et je ne regex que les deux dernières semaines, donc je suis sûr qu'il manque certaines nuances. Cela dit, pour les petites collections de chaînes (les miennes sont dans un cadre de données de 12 000 lignes et 40 colonnes impaires), comme dernière étape après un passage pour la suppression des caractères étrangers, cela fonctionne exceptionnellement bien, surtout si vous introduisez des espaces supplémentaires où vous vous voulez séparer le texte joint par un caractère autre qu'un mot, mais vous ne voulez pas ajouter d'espaces là où il n'y en avait pas auparavant.

Un exemple:

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)

Cela produit:

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'

Donc, strip supprime un espace à la fois. Donc, dans le cas des PO, ça strip()va. mais si les choses deviennent plus complexes, l'expression régulière et un modèle similaire peuvent être d'une certaine valeur pour des paramètres plus généraux.

le voir en action

joshua fiddler
la source
0

essayez de traduire

>>> 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'
海洋 顶端
la source
0

Si vous souhaitez supprimer l'espace blanc uniquement au début et à la fin de la chaîne, vous pouvez faire quelque chose comme ceci:

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

Cela fonctionne beaucoup comme la méthode QString :: trimmed () de Qt, en ce sens qu'elle supprime les espaces de début et de fin, tout en laissant les espaces internes seuls.

Mais si vous souhaitez quelque chose comme la méthode QString :: simplified () de Qt qui non seulement supprime les espaces blancs de début et de fin, mais également "écrase" tous les espaces blancs internes consécutifs en un seul caractère d'espace, vous pouvez utiliser une combinaison de .split()et " ".join, comme ceci:

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

Dans ce dernier exemple, chaque séquence d'espaces internes est remplacée par un seul espace, tout en supprimant les espaces au début et à la fin de la chaîne.

JL
la source
-1

En général, j'utilise la méthode suivante:

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

Remarque: Ceci sert uniquement à supprimer "\ n", "\ r" et "\ t" uniquement. Il ne supprime pas les espaces supplémentaires.

Mayur Koshti
la source
-2

pour supprimer les espaces blancs du milieu de la chaîne

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

production:

ATGCGACACGATCGACC
Maître Roshi
la source
1
cette question concerne python, pas Javascript ou perl
phuclv
-17

Cela supprimera tous les espaces et les sauts de ligne du début et de la fin d'une chaîne:

>>> s = "  \n\t  \n   some \n text \n     "
>>> re.sub("^\s+|\s+$", "", s)
>>> "some \n text"
Rafe
la source
8
Pourquoi utiliser une expression régulière quand s.strip()fait exactement cela?
Ned Batchelder
1
s.strip()ne gère que l' espace blanc initial , mais pas les espaces "découverts" après avoir supprimé les autres caractères indésirables. Notez que cela supprimera même les espaces blancs après le dernier classement\n
Rafe
Quelqu'un a voté contre cette réponse mais n'a pas expliqué pourquoi elle est défectueuse. Honte à vous (@NedBatchelder si le vote négatif était vous, inversez s'il vous plait car j'ai expliqué votre question et vous n'avez rien dit de réellement cassé avec ma réponse)
Rafe
10
Rafe, vous voudrez peut-être revérifier: s.strip()produit exactement le même résultat que votre regex.
Ned Batchelder
3
@Rafe, vous le confondez avec le trim. Strip effectue les opérations requises.
iMitwe