2015-08-10 16 views
7

La stringa di origine è:Python re.findall si comporta in modo strano

# Python 3.4.3 
s = r'abc123d, hello 3.1415926, this is my book' 

e qui è il mio modello:

pattern = r'-?[0-9]+(\\.[0-9]*)?|-?\\.[0-9]+' 

tuttavia, re.search mi può dare risultato corretto:

m = re.search(pattern, s) 
print(m) # output: <_sre.SRE_Match object; span=(3, 6), match='123'> 

re.findall scarica semplicemente una lista vuota:

L = re.findall(pattern, s) 
print(L) # output: ['', '', ''] 

perché non può re.findall dammi la lista atteso:

['123', '3.1415926'] 
+0

sua volta cattura gruppo gruppo non catturante. –

+0

@AvinashRaj, um .., se rimuovo quel gruppo di cattura, anche ri.la ricerca mi dà un risultato None –

+0

@stribizhev, non lo è, '3.1415926' dovrebbe essere un numero float nel risultato –

risposta

6
s = r'abc123d, hello 3.1415926, this is my book' 
print re.findall(r'-?[0-9]+(?:\.[0-9]*)?|-?\.[0-9]+',s) 

Non avete bisogno di escape due volte quando si utilizza raw mode.

uscita: ['123', '3.1415926']

anche il tipo di ritorno sarà un elenco di strings Se lo volete tipo di ritorno, integers e floats uso map

import re,ast 
s = r'abc123d, hello 3.1415926, this is my book' 
print map(ast.literal_eval,re.findall(r'-?[0-9]+(?:\.[0-9]*)?|-?\.[0-9]+',s)) 

uscita: [123, 3.1415926]

+2

Sebbene questa espressione regolare sia inferiore efficiente del mio, ammetto che il trucco con 'ast' è bello (anche se non richiesto nel PO). –

+1

@stribizhev ho letto uno dei suoi commenti .... '@stribizhev, non lo è, '3.1415926' dovrebbe essere un numero float nel risultato 'quindi ho incluso quello nella mia risposta :) – vks

+0

voi due siete entrambi geni, è difficile per me scegliere quale accettare. :) –

6

Nel tuo caso, findall tornati tutti i testi che sono stati catturati vuoto perchè avete \\ entro r'' stringa letterale che hanno cercato di abbinare un letterale \ . Vedere findall reference:

Se uno o più gruppi sono presenti nel modello, restituire un elenco di gruppi; questo sarà un elenco di tuple se il modello ha più di un gruppo. Le partite vuote sono incluse nel risultato a meno che non tocchino l'inizio di un'altra partita.

per abbinare i numeri, è necessario utilizzare

-?\d*\.?\d+ 

Le partite regex:

  • -? - meno opzionale segno
  • \d* - opzionale cifre
  • \.? - opzionale separatore decimale
  • \d+ - 1 o più cifre.

Vedi demo

Ecco IDEONE demo:

import re 
s = r'abc123d, hello 3.1415926, this is my book' 
pattern = r'-?\d*\.?\d+' 
L = re.findall(pattern, s) 
print(L) 
Problemi correlati