Comment supprimer tous les caractères sauf les chiffres d'une chaîne de caractères ?
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.
Comment supprimer tous les caractères sauf les chiffres d'une chaîne de caractères ?
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'
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.
@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
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.
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.
@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!-).
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.
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")