2011-02-10 16 views
10

Ho una lista di modelli esatti che voglio cercare in una determinata stringa. Attualmente ho una soluzione davvero brutta per un problema del genere.Come abbinare le stringhe "multiple" esatte in Python

pat1 = re.compile('foo.tralingString') 
mat1 = pat1.match(mystring) 

pat2 = re.compile('bar.trailingString') 
mat2 = pat2.match(mystring) 

if mat1 or mat2: 
    # Do whatever 

pat = re.compile('[foo|bar].tralingString') 
match = pat.match(mystring) # Doesn't work 

L'unica condizione è che ho un elenco di stringhe che devono corrispondere esattamente. Qual è la migliore soluzione possibile in Python.

MODIFICA: gli schemi di ricerca hanno alcuni schemi finali comuni.

risposta

16

Si potrebbe fare una regex banale che unisce quei due:

pat = re.compile('foo|bar') 
if pat.match(mystring): 
    # Do whatever 

Si potrebbe quindi espandere l'espressione regolare di fare tutto ciò è necessario, utilizzando il | di separazione (che significa o nella sintassi regex)

Edit: in base alla tua recente modifica, questo dovrebbe farlo per voi:

pat = re.compile('(foo|bar)\\.trailingString'); 
if pat.match(mystring): 
    # Do Whatever 

[] è una classe di caratteri. Quindi il tuo [foo|bar] corrisponderebbe a una stringa con uno dei caratteri inclusi (poiché non ci sono * o + o? Dopo la classe). () è il contenitore per un modello secondario.

+0

In realtà il problema è un po 'più complicato. I miei schemi di ricerca sono come '1. foo.trailingString 2. bar.trailingString'. Ho provato a fare '[foo | bar] .trailingString', ma questo fallisce. – Neo

+0

@Neo: questo cambia la domanda, non è vero? prova '(foo | bar) .trailingString' (anche se non sono sicuro al 100% della sintassi regex di Python) ... – ircmaxell

+0

@ircmaxell: Python ha una sintassi simile a PCRE con solo poche differenze credo. – BoltClock

7

Hai ragione usando | ma stai utilizzando una classe di caratteri [] invece di un subpattern (). Prova questo regex:

r = re.compile('(?:foo|bar)\.trailingString') 

if r.match(mystring): 
    # Do stuff 

Vecchio risposta

Se si vuole fare sottostringa corrispondenze esatte non si dovrebbe usare espressioni regolari.

provare a utilizzare in invece:

words = ['foo', 'bar'] 

# mystring contains at least one of the words 
if any(i in mystring for i in words): 
    # Do stuff 
+0

Dai un'occhiata alla modifica. Tutti i modelli di ricerca hanno alcune parti finali comuni. Quindi speravo di usare Re in qualche modo. – Neo

+0

@Neo: ho modificato la mia risposta. – BoltClock

0

forse

any([re.match(r, mystring) for r in ['bar', 'foo']]) 

Sto assumendo le vostre corrispondenze di una sequenza sarà più complessa di quanto foo o bar; se non lo sono, basta usare

if mystring in ['bar', 'foo']: 
1

Usa '|' nella tua espressione regolare. Sta per "OR". Non c'è modo migliore troppo, quando si desidera re.escape le corde

pat = re.compile('|'.join(map(re.escape, ['foo.tralingString','bar.tralingString','something.else']))) 
1

Volete cercare modelli o stringhe?La soluzione migliore per ogni è molto diverso:

# strings 
patterns = ['foo', 'bar', 'baz'] 
matches = set(patterns) 

if mystring in matches:  # O(1) - very fast 
    # do whatever 


# patterns 
import re 
patterns = ['foo', 'bar'] 
matches = [re.compile(pat) for pat in patterns] 

if any(m.match(mystring) for m in matches): # O(n) 
    # do whatever 

Edit: Ok, vuoi per cercare stringhe di lunghezza variabile esatte all'inizio di una stringa di ricerca; prova

from collections import defaultdict 
matches = defaultdict(set) 

patterns = ['foo', 'barr', 'bazzz'] 
for p in patterns: 
    matches[len(p)].add(p) 

for strlen,pats in matches.iteritems(): 
    if mystring[:strlen] in pats: 
     # do whatever 
     break 
Problemi correlati