2013-03-11 17 views
38

Python 2.7.1 Sto cercando di usare Python un'espressione regolare per estrarre le parole all'interno di un modelloPython modello estratto corrisponde

ho qualche stringa che assomiglia a questo

someline abc 
someother line 
name my_user_name is valid 
some more lines 

Voglio estrarre la parola "my_user_name". Faccio qualcosa come

import re 
s = #that big string 
p = re.compile("name .* is valid", re.flags) 
p.match(s) #this gives me <_sre.SRE_Match object at 0x026B6838> 

Come estrarre my_user_name ora?

risposta

50

È necessario acquisire dalle espressioni regolari. search per il modello, se trovato, recuperare la stringa utilizzando group(index). Supponendo che vengano effettuati controlli validi:

>>> p = re.compile("name (.*) is valid") 
>>> p.search(s) # The result of this is referenced by variable name '_' 
<_sre.SRE_Match object at 0x10555e738> 
>>> _.group(1)  # group(1) will return the 1st capture. 
'my_user_name' 
+4

Sei sicuro che non è 'gruppo (0)' per la prima partita? – sharshofski

+10

Tipo di ritardo, ma sia sì che no. 'group (0)' restituisce il testo corrispondente, non il primo gruppo di cattura. Il commento del codice è corretto, mentre sembra che tu stia confondendo i gruppi di cattura e le partite. 'group (1)' restituisce il primo gruppo di cattura. – andrewgu

20

È possibile utilizzare la corrispondenza gruppi:

p = re.compile('name (.*) is valid') 

esempio

>>> import re 
>>> p = re.compile('name (.*) is valid') 
>>> s = """ 
... someline abc 
... someother line 
... name my_user_name is valid 
... some more lines""" 
>>> p.findall(s) 
['my_user_name'] 

Qui io uso re.findall piuttosto che re.search per ottenere tutte le istanze di my_user_name. Utilizzando re.search, avresti bisogno di ottenere i dati dal gruppo sull'oggetto partita:

>>> p.search(s) #gives a match object or None if no match is found 
<_sre.SRE_Match object at 0xf5c60> 
>>> p.search(s).group() #entire string that matched 
'name my_user_name is valid' 
>>> p.search(s).group(1) #first group that match in the string that matched 
'my_user_name' 

Come accennato nei commenti, si potrebbe desiderare di fare il vostro regex non avido:

p = re.compile('name (.*?) is valid') 

per prendere solo la roba tra il 'name ' e la prossima ' is valid' (piuttosto che permettere la vostra regex per raccogliere altri ' is valid' nel tuo gruppo.

+2

E' possibile è necessario un match non avido ... (a meno che un nome utente non possa essere più parole ...) –

+0

@JonClements - Intendi '(. *?)'? Sì, è possibile, anche se non è necessario a meno che non usiamo 're.DOTALL' – mgilson

+0

yeah -' re.findall ('nome (. *) È valido', 'nome jon clements è valido è valido') 'probabilmente vinto Non si ottengono i risultati desiderati ... –

7

Si desidera un capture group.

p = re.compile("name (.*) is valid", re.flags) # parentheses for capture groups 
print p.match(s).groups() # This gives you a tuple of your matches. 
9

Si potrebbe usare qualcosa di simile:

import re 
s = #that big string 
# the parenthesis create a group with what was matched 
# and '\w' matches only alphanumeric charactes 
p = re.compile("name +(\w+) +is valid", re.flags) 
# use search(), so the match doesn't have to happen 
# at the beginning of "big string" 
m = p.search(s) 
# search() returns a Match object with information about what was matched 
if m: 
    name = m.group(1) 
else: 
    raise Exception('name not found') 
2

Forse è un po 'più breve e più facile da capire:

import re 
text = '... someline abc... someother line... name my_user_name is valid.. some more lines' 
>>> re.search('name (.*) is valid', text).group(1) 
'my_user_name' 
Problemi correlati