155 votes

Supprimer les caractères sauf les chiffres d'une chaîne de caractères en utilisant Python ?

Comment supprimer tous les caractères sauf les chiffres d'une chaîne de caractères ?

0 votes

@Jan Tojnar : Pouvez-vous donner un exemple ?

0 votes

@JG : J'ai gtk.Entry() et je veux qu'on y entre un multiple de float.

1 votes

@JanTojnar utilise la méthode re.sub comme dans la réponse deux et liste explicitement les caractères à conserver e.g. re.sub("[^0123456789 \. ]","","poo123.4and5fish")

228voto

João Silva Points 36619

Utilisez re.sub comme ça :

>>> import re
>>> re.sub('\D', '', 'aas30dsa20')
'3020'

\D correspond à tout caractère non numérique. Ainsi, le code ci-dessus remplace essentiellement chaque caractère non numérique par la chaîne vide.

Ou vous pouvez utiliser filter comme suit (dans Python 2) :

>>> filter(str.isdigit, 'aas30dsa20')
'3020'

Puisque dans Python 3, filter renvoie un itérateur au lieu d'un list vous pouvez utiliser la formule suivante à la place :

>>> ''.join(filter(str.isdigit, 'aas30dsa20'))
'3020'

0 votes

re est un mal pour une tâche aussi simple, la seconde est la meilleure je pense, car les méthodes 'is...' sont les plus rapides pour les chaînes de caractères.

0 votes

votre exemple de filtre est limité à py2k

2 votes

@f0b0s-iu9-info : avez-vous chronométré ? sur ma machine (py3k) re est deux fois plus rapide que le filtre avec isdigit générateur avec isdigt est à mi-chemin entre les deux

117voto

Alex Martelli Points 330805

Dans Python 2.*, l'approche de loin la plus rapide est la méthode .translate méthode :

>>> x='aaa12333bb445bb54b5b52'
>>> import string
>>> all=string.maketrans('','')
>>> nodigs=all.translate(all, string.digits)
>>> x.translate(all, nodigs)
'1233344554552'
>>> 

string.maketrans crée une table de traduction (une chaîne de longueur 256) qui, dans ce cas, est identique à ''.join(chr(x) for x in range(256)) (juste plus rapide à faire;-). .translate applique la table de traduction (qui ici n'est pas pertinente puisque all signifie essentiellement identité) ET supprime les caractères présents dans le second argument -- la partie clé.

.translate fonctionne très différemment sur les chaînes Unicode (et les chaînes en Python 3 -- je faire Les questions de souhaits précisent quelle version majeure de Python est intéressante !) -- pas tout à fait aussi simple, pas tout à fait aussi rapide, mais tout à fait utilisable.

De retour à 2.*, la différence de performance est impressionnante... :

$ python -mtimeit -s'import string; all=string.maketrans("", ""); nodig=all.translate(all, string.digits); x="aaa12333bb445bb54b5b52"' 'x.translate(all, nodig)'
1000000 loops, best of 3: 1.04 usec per loop
$ python -mtimeit -s'import re;  x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'
100000 loops, best of 3: 7.9 usec per loop

Accélérer les choses de 7 à 8 fois, c'est loin d'être négligeable. translate vaut la peine d'être connue et utilisée. L'autre approche populaire non-RE... :

$ python -mtimeit -s'x="aaa12333bb445bb54b5b52"' '"".join(i for i in x if i.isdigit())'
100000 loops, best of 3: 11.5 usec per loop

est 50% plus lent que RE, donc le .translate le dépasse de plus d'un ordre de grandeur.

En Python 3, ou pour Unicode, vous devez passer .translate un mappage (avec des ordinaux, et non des caractères directement, comme clés) qui retourne None pour ce que vous voulez supprimer. Voici une façon pratique d'exprimer cela pour la suppression de "tout sauf" quelques caractères :

import string

class Del:
  def __init__(self, keep=string.digits):
    self.comp = dict((ord(c),c) for c in keep)
  def __getitem__(self, k):
    return self.comp.get(k)

DD = Del()

x='aaa12333bb445bb54b5b52'
x.translate(DD)

émet également '1233344554552' . Cependant, en mettant cela dans xx.py nous avons... :

$ python3.1 -mtimeit -s'import re;  x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'
100000 loops, best of 3: 8.43 usec per loop
$ python3.1 -mtimeit -s'import xx; x="aaa12333bb445bb54b5b52"' 'x.translate(xx.DD)'
10000 loops, best of 3: 24.3 usec per loop

...qui montre que l'avantage de performance disparaît, pour ce type de tâches de "suppression", et devient une diminution de performance.

0 votes

complet, en particulier la partie Python3.x(Unicode). Peut-être qu'Unicode est plus puissant dans un domaine beaucoup plus vaste, par exemple : supprimer les caractères sauf les caractères chinois des chaînes Unicode.

1 votes

@sunqiang, oui, absolument -- il y a une raison pour laquelle Py3k a adopté Unicode comme type de chaîne de texte, au lieu des chaînes d'octets comme dans Py2 -- la même raison pour laquelle Java et C# ont toujours eu le même mème "string means unicode"... un peu de surcharge, peut-être, mais un bien meilleur support pour tout ce qui n'est pas anglais!-).

0 votes

Tout cela est très bien, mais les expressions régulières le font en une seule ligne !

66voto

f0b0s Points 1130
s=''.join(i for i in s if i.isdigit())

Une autre variante du générateur.

0 votes

C'était génial +1. Ça aurait été encore mieux si on avait utilisé Lamda.

0 votes

Si vous voulez inclure des caractères personnalisés, par exemple inclure des négatifs ou des décimales, faites-le : s = ''.join(i for i in s if i.isdigit() or i in '-./\\')

17voto

freiksenet Points 1764

Vous pouvez utiliser le filtre :

filter(lambda x: x.isdigit(), "dasdasd2313dsa")

Sur python3.0 vous devez joindre ceci (un peu laid :( ))

''.join(filter(lambda x: x.isdigit(), "dasdasd2313dsa"))

0 votes

seulement dans py2k, dans py3k il retourne un générateur

0 votes

convertir str à list pour être sûr qu'il fonctionne à la fois sur py2 et py3 : ''.join(filter(lambda x: x.isdigit(), list("dasdasd2313dsa")))

14voto

SilentGhost Points 79627

dans le sens de la réponse de Bayer :

''.join(i for i in s if i.isdigit())

0 votes

Non, cela ne fonctionnera pas pour les nombres négatifs car - n'est pas un chiffre.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X