2013-07-01 12 views
9

Sto cercando di abbinare un modello a stringhe che potrebbero avere più istanze del pattern. Ho bisogno di ogni istanza separatamente. re.findall()dovrebbe farlo ma non so cosa sto facendo male.Python regex per corrispondere più volte

pattern = re.compile('/review: (http://url.com/(\d+)\s?)+/', re.IGNORECASE) 
match = pattern.findall('this is the message. review: http://url.com/123 http://url.com/456') 

Ho bisogno 'http://url.com/123', http://url.com/456 ei due numeri 123 & 456 di essere diversi elementi della lista match.

Ho anche provato '/review: ((http://url.com/(\d+)\s?)+)/' come lo schema, ma senza fortuna.

+0

è sufficiente rimuovere la recensione: parte come secondo http non avrà che prima di esso. – abc123

+0

sì, ma ho bisogno che lì, è parte della regex. Non ho bisogno di alcun URL qui, solo quelli che seguono la recensione della stringa: ' – mavili

risposta

12

Utilizzare questo. È necessario posizionare la 'revisione' al di fuori del gruppo di acquisizione per ottenere il risultato desiderato.

pattern = re.compile(r'(?:review:)?(http://url.com/(\d+))\s?', re.IGNORECASE) 

Questo dà uscita

>>> match = pattern.findall('this is the message. review: http://url.com/123 http://url.com/456') 
>>> match 
[('http://url.com/123', '123'), ('http://url.com/456', '456')] 
+0

che fa il lavoro, grazie! anche il '?' dopo '(?: review)' è critico in quanto non mi ha dato tutte le corrispondenze senza di esso. ;) – mavili

+0

Non dimenticare di importare re' – Rambatino

5

Hai extra/'s nella regex. In Python il pattern dovrebbe essere solo una stringa. per esempio. invece di questo:

pattern = re.compile('/review: (http://url.com/(\d+)\s?)+/', re.IGNORECASE) 

dovrebbe essere:

pattern = re.compile('review: (http://url.com/(\d+)\s?)+', re.IGNORECASE) 

anche tipicamente in python che ci si effettivamente utilizzare una stringa "grezzo" come questo:

pattern = re.compile(r'review: (http://url.com/(\d+)\s?)+', re.IGNORECASE) 

La r supplementare su la parte anteriore della stringa ti evita di dover eseguire molto backslash di escape, ecc.

0

Utilizzare un approccio in due fasi: innanzitutto ottenere tutto g da "review:" a EOL, quindi tokenize that.

msg = 'this is the message. review: http://url.com/123 http://url.com/456' 

review_pattern = re.compile('.*review: (.*)$') 
urls = review_pattern.findall(msg)[0] 

url_pattern = re.compile("(http://url.com/(\d+))") 
url_pattern.findall(urls) 
Problemi correlati