164 votes

Comment extraire un nombre flottant d'une chaîne

J'ai un certain nombre de chaînes similaires à Current Level: 13.4 db. et je voudrais extraire seulement le nombre à virgule flottante. Je dis flottant et non décimal car il est parfois entier. RegEx peut-il faire cela ou y a-t-il un meilleur moyen ?

325voto

miku Points 63392

Si votre flottant est toujours exprimé en notation décimale quelque chose comme

>>> import re
>>> re.findall("\d+\.\d+", "Current Level: 13.4db.")
['13.4']

peut suffire.

Une version plus robuste serait :

>>> re.findall(r"[-+]?(?:\d*\.\d+|\d+)", "Current Level: -13.2db or 14.2 or 3")
['-13.2', '14.2', '3']

Si vous souhaitez valider la saisie utilisateur, vous pouvez également vérifier la présence d'un flotteur en y accédant directement :

user_input = "Current Level: 1e100 db"
for token in user_input.split():
    try:
        # if this succeeds, you have your (first) float
        print float(token), "is a float"
    except ValueError:
        print token, "is something else"

# => Would print ...
#
# Current is something else
# Level: is something else
# 1e+100 is a float
# db is something else
        

90voto

John Machin Points 39706

Vous pouvez essayer quelque chose comme ça qui couvre toutes les bases, y compris ne pas compter sur l'espace après le nombre :

>>> import re
>>> numeric_const_pattern = r"""
...     [-+]? # optional sign
...     (?:
...         (?: \d* \. \d+ ) # .1 .12 .123 etc 9.1 etc 98.1 etc
...         |
...         (?: \d+ \.? ) # 1. 12. 123. etc 1 12 123 etc
...     )
...     # followed by optional exponent part if desired
...     (?: [Ee] [+-]? \d+ ) ?
...     """
>>> rx = re.compile(numeric_const_pattern, re.VERBOSE)
>>> rx.findall(".1 .12 9.1 98.1 1. 12. 1 12")
['.1', '.12', '9.1', '98.1', '1.', '12.', '1', '12']
>>> rx.findall("-1 +1 2e9 +2E+09 -2e-9")
['-1', '+1', '2e9', '+2E+09', '-2e-9']
>>> rx.findall("current level: -2.03e+99db")
['-2.03e+99']
>>>

Pour un copiage facile :

numeric_const_pattern = '[-+]? (?: (?: \d* \. \d+ ) | (?: \d+ \.? ) )(?: [Ee] [+-]? \d+ ) ?'
rx = re.compile(numeric_const_pattern, re.VERBOSE)
rx.findall("Some example: Jr. it. was .23 between 2.3 and 42.31 seconds")

38voto

IceArdor Points 678

Python docs a une réponse qui couvre +/-, et la notation de l'exposant

scanf() Token      Regular Expression
%e, %E, %f, %g     [-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?
%i                 [-+]?(0[xX][\dA-Fa-f]+|0[0-7]*|\d+)

Cette expression régulière ne prend pas en charge les formats internationaux où une virgule est utilisée comme caractère séparateur entre la partie entière et la partie fractionnaire (3,14159). Dans ce cas, remplacez tout \. par [.,] dans le fichier flottant ci-dessus.

                        Regular Expression
International float     [-+]?(\d+([.,]\d*)?|[.,]\d+)([eE][-+]?\d+)?

12voto

Martin Points 31
re.findall(r"[-+]?\d*\.?\d+|\d+", "Current Level: -13.2 db or 14.2 or 3")

comme décrit ci-dessus, fonctionne vraiment bien ! Une suggestion cependant :

re.findall(r"[-+]?\d*\.?\d+|[-+]?\d+", "Current Level: -13.2 db or 14.2 or 3 or -3")

renverra également des valeurs d'int négatives (comme -3 à la fin de cette chaîne)

7voto

user3613331 Points 13

Vous pouvez utiliser la règle suivante pour obtenir des valeurs entières et flottantes à partir d'une chaîne :

re.findall(r'[\d\.\d]+', 'hello -34 42 +34.478m 88 cricket -44.3')

['34', '42', '34.478', '88', '44.3']

Merci Rex

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