2008-12-22 7 views
24

Comment extraire une valeur double d'une chaîne en utilisant regex.Extrait float/valeur double

import re 

pattr = re.compile(???)  
x = pattr.match("4.5")  
+0

Pouvez-vous fournir quelques détails sur pourquoi vous ne pouvez pas utiliser float ("4.5")? – jfs

Répondre

20

Voici le chemin facile. N'utilisez pas regex pour les types intégrés.

try: 
    x = float(someString) 
except ValueError, e: 
    # someString was NOT floating-point, what now? 
+0

En fait, c'est aussi le moyen le plus sûr. Considérons une mauvaise entrée, comme '0..1',' 0.0.02', il est très difficile pour regex de le reconnaître. Le pire, c'est de prétendre que c'est correct et de produire une mauvaise réponse. – dspjm

+0

Techniquement correct, mais la question spécifie explicitement regexp. – VillasV

45

Une expression rationnelle de la perldoc perlretut:

import re 
re_float = re.compile("""(?x) 
^
     [+-]?\ *  # first, match an optional sign *and space* 
     (   # then match integers or f.p. mantissas: 
      \d+  # start out with a ... 
      (
       \.\d* # mantissa of the form a.b or a. 
     )?  # ? takes care of integers of the form a 
     |\.\d+  # mantissa of the form .b 
    ) 
     ([eE][+-]?\d+)? # finally, optionally match an exponent 
    $""") 
m = re_float.match("4.5") 
print m.group(0) 
# -> 4.5 

Pour extraire les numéros d'une grande chaîne:

s = """4.5 abc -4.5 abc - 4.5 abc + .1e10 abc . abc 1.01e-2 abc 
     1.01e-.2 abc 123 abc .123""" 
print re.findall(r"[+-]? *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?", s) 
# -> ['4.5', '-4.5', '- 4.5', '+ .1e10', ' 1.01e-2', 
#  '  1.01', '-.2', ' 123', ' .123'] 
+2

L'expression findall est l'affaire, merci – reabow

1

un flottant comme expression régulière en force brute. il y a des petites différences par rapport à la version de JF Sebastian:

import re 
if __name__ == '__main__': 
    x = str(1.000e-123) 
    reFloat = r'(^[+-]?\d+(?:\.\d+)?(?:[eE][+-]\d+)?$)' 
    print re.match(reFloat,x) 

>>> <_sre.SRE_Match object at 0x0054D3E0> 
+0

Ceci ne correspond pas aux flottants sans une partie entière, par ex. '.123' au lieu de' 0.123'. –

9

Pour Parse int et float valeurs (séparateur point):

re.findall(r'\d+\.*\d*', 'some 12 12.3 0 any text 0.8') 

Résultat:

['12', '12.3', '0', '0.8'] 
+0

Si vous pouvez offrir une procédure pour obtenir l'int ou le flottant, mais sans être dans un dictionnaire ou un tableau, cela serait utile. ce que j'ai 'str1 =" BIOS: version 2.0.0 "' ce que je veux '2.0.0' sans toute virgule ou crochets. –

+1

Bonjour, vous pouvez utiliser comme: re.findall (r '[\ d \.] +', "BIOS: version 2.0.0") –

+0

mieux: re.findall (r '[\ d \.] {2, } | \ d + ', "BIOS: version 2.0.0") –