671 votes

Python: extrait des nombres d'une chaîne

Je voudrais extraire tous les nombres contenus dans une chaîne. Quel est le mieux adapté au but, aux expressions régulières ou à la méthode isdigit() ?

Exemple:

 line = "hello 12 hi 89"
 

Résultat:

 [12, 89]
 

714voto

Vincent Savard Points 12215

J'utiliserais une expression rationnelle:

 >>> import re
>>> re.findall(r'\d+', 'hello 42 I\'m a 32 string 30')
['42', '32', '30']
 

Cela correspondrait également à 42 bla42bla . Si vous voulez uniquement des nombres délimités par des limites de mots (espace, point, virgule), vous pouvez utiliser \ b:

 >>> re.findall(r'\b\d+\b', 'he33llo 42 I\'m a 32 string 30')
['42', '32', '30']
 

delnan a un bon point (voir commentaires): vous pouvez mapper int() sur la liste pour convertir les chaînes en entiers.

685voto

fmark Points 15028

Si vous souhaitez uniquement extraire uniquement les nombres entiers positifs, essayez les solutions suivantes:

>>> str = "h3110 23 cat 444.4 rabbit 11 2 dog"
>>> [int(s) for s in str.split() if s.isdigit()]
[23, 11, 2]

Je dirais que c'est mieux que la regex exemple, pour trois raisons. Tout d'abord, vous n'avez pas besoin d'un autre module; d'autre part, c'est plus lisible, car vous n'avez pas besoin d'analyser les regex mini-langage; et la troisième, elle est plus rapide (et donc probablement plus pythonic):

python -m timeit -s "str = 'h3110 23 cat 444.4 rabbit 11 2 dog' * 1000" "[s for s in str.split() if s.isdigit()]"
100 loops, best of 3: 2.84 msec per loop

python -m timeit -s "import re" "str = 'h3110 23 cat 444.4 rabbit 11 2 dog' * 1000" "re.findall('\\b\\d+\\b', str)"
100 loops, best of 3: 5.66 msec per loop

Ce ne reconnaîtra pas les chars, les entiers négatifs, ou les entiers en format hexadécimal. Si vous ne pouvez pas accepter ces limites, slim réponse ci-dessous fera l'affaire.

85voto

jmnas Points 396

Je suppose que vous voulez des flotteurs, pas seulement des entiers, donc je ferais quelque chose comme ceci:

 l = []
for t in s.split():
    try:
        l.append(float(t))
    except ValueError:
        pass
 

Notez que certaines des autres solutions affichées ici ne fonctionnent pas avec des nombres négatifs:

 >>> re.findall(r'\b\d+\b', 'he33llo 42 I\'m a 32 string -30')
['42', '32', '30']

>>> '-3'.isdigit()
False
 

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