2012-12-25 14 views
6

Quando provo a utilizzare l'espressione regolare per trovare le stringhe in altre stringhe, non funziona come previsto. Ecco un esempio:Cerca stringhe usando un'espressione regolare in Python

import re 
message = 'I really like beer, but my favourite beer is German beer.' 
keywords = ['beer', 'german beer', 'german'] 

regex = re.compile("|".join(keywords)) 
regex.findall(message.lower()) 

Risultato:

['beer', 'beer', 'german beer'] 

Ma il risultato atteso sarebbe:

['beer', 'beer', 'german beer', 'german'] 

Un altro modo per farlo potrebbe essere:

results = [] 
for k in keywords: 
    regex = re.compile(k) 
    for r in regex.findall(message.lower()): 
     results.append(r) 

['beer', 'beer', 'beer', 'german beer', 'german'] 

Funziona come voglio, ma penso che sia n o il modo migliore per farlo. Qualcuno può aiutarmi?

risposta

6

re.findall Impossibile trovare corrispondenze sovrapposte. Se si desidera utilizzare espressioni regolari, è necessario creare espressioni separate ed eseguirle in un ciclo come nel secondo esempio.

Nota che il secondo esempio può anche essere abbreviato in seguito, anche se è una questione di gusto se trovi questo più leggibile:

results = [r for k in keywords for r in re.findall(k, message.lower())] 

tuo esempio specifico non richiede l'uso di espressioni regolari. Dovresti evitare di usare espressioni regolari se vuoi solo trovare stringhe fisse.

+0

L'interrogante non vuole solo per verificare se una particolare stringa è parte di una stringa, ma vuole che tutte le occorrenze di una particolare stringa. In questo caso, l'uso di 're.findall()' è il modo migliore per farlo. Evitare le espressioni regolari renderebbe questa soluzione più laboriosa del necessario. – pemistahl

+0

Grazie ragazzi per le vostre risposte. Ora so che sto usando una funzione sbagliata (findall), quindi cosa consiglia per trovare le corrispondenze, incluse le sovrapposizioni? –

+0

@ Adrián: Hai bisogno del potere delle espressioni regolari o vuoi solo trovare stringhe fisse? –

6

re.findall è descritto in http://docs.python.org/2/library/re.html

"Ritorno tutte le partite che non si sovrappongono su modello in stringa ..."

non sovrapposizione significa che per "la birra tedesca" non troverà "birra tedesca" E "tedesco", perché quelle partite si sovrappongono.

+0

Grazie per la tua risposta Omri Barel. Cosa consiglia per trovare le corrispondenze, incluse le sovrapposizioni? –

+0

In generale devi fare ciò che hai fatto: una parola chiave alla volta. Ma per una soluzione migliore dovrai descrivere ciò che stai realmente cercando di fare (ad esempio, qual è la situazione attuale senza semplificare a esempi banali). –

+0

Omri, come ho scritto nella risposta, ho chiesto delle espressioni regolari perché stavo pensando che sia il modo migliore e ottimale per farlo. Le stringhe di find saranno sempre fisse (word1 | word2 | word3 ...), voglio dire nessuna regex complessa. –

1

mio più pulito (per me) la versione per la vostra ultima soluzione

results = [] 
for key in keywords: 
    results.extend(re.findall(key, message, re.IGNORECASE)) 
Problemi correlati