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