web-dev-qa-db-fra.com

Supprimer les espaces dans Python en utilisant string.whitespace

Le string.whitespace de Python est génial:

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

Comment puis-je utiliser cela avec une chaîne sans recourir à la saisie manuelle de '\ t |\n | ... etc pour regex?

Par exemple, il devrait pouvoir tourner: "S'il vous plaît\n ne me faites pas de mal\x0b moi."

dans

"S'il te plaît, ne me fais pas de mal."

Je voudrais probablement garder les espaces simples, mais ce serait assez facile d'aller simplement string.whitespace [: - 1] je suppose.

47
Alex

Il existe un raccourci spécial pour exactement ce cas d'utilisation!

Si vous appelez str.split sans argument, il se divise en séquences d'espaces au lieu de caractères uniques. Alors:

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

Quel est le problème avec le \s classe de caractère?

>>> import re

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

Faisons quelques hypothèses raisonnables:

(1) Vous voulez vraiment remplacer n'importe quelle série de caractères d'espacement par un seul espace (une séquence est de longueur 1 ou plus).

(2) Vous souhaitez que le même code fonctionne avec des modifications minimales sous Python 2.X avec des objets Unicode.

(3) Vous ne voulez pas que votre code suppose des choses qui ne sont pas garanties dans les documents

(4) Vous souhaitez que le même code fonctionne avec des modifications minimales avec les objets Python 3.X str.

La réponse actuellement sélectionnée présente les problèmes suivants:

(a) change " " * 3 en " " * 2 c'est-à-dire qu'il supprime les espaces en double mais pas les espaces en triple, quadruple, etc. [échoue à l'exigence 1]

(b) remplace "foo\tbar\tzot" par "foobarzot" [échec de l'exigence 1]

(c) lors de l'alimentation d'un objet unicode, obtient TypeError: translate() takes exactly one argument (2 given) [échec de l'exigence 2]

(d) utilise string.whitespace[:-1] [échoue l'exigence 3; l'ordre des caractères dans string.whitespace n'est pas garanti]

(e) utilise string.whitespace[:-1] [échoue l'exigence 4; dans Python 2.X, string.whitespace est '\t\n\x0b\x0c\r '; dans Python 3.X, il est '\ t\n\r\x0b\x0c ']

La réponse " ".join(s.split()) et la réponse re.sub(r"\s+", " ", s) n'ont pas ces problèmes.

9
John Machin

Vous pouvez utiliser la méthode de traduction

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

Et puis supprimez les espaces en double

s.replace('  ', ' ')
>>> s
"Please don't hurt me."
2
Tor Valamo

un point de départ .. (bien qu'il ne soit pas plus court que d'assembler manuellement le cirque des espaces blancs) ..

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

Ou si vous souhaitez réduire les espaces au maximum à 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."

Troisième voie, plus compacte:

>>> 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."
1
miku