Vorrei assumere una regex è migliore di controllo per ogni sottostringa singolarmente perché concettualmente l'espressione regolare è modellato come un DFA, e così come l'ingresso è consumato tutte le partite vengono testati contemporaneamente (risultante in una scansione della stringa di input).
Quindi, ecco un esempio:
import re
def work():
to_find = re.compile("cat|fish|dog")
search_str = "blah fish cat dog haha"
match_obj = to_find.search(search_str)
the_index = match_obj.start() # produces 5, the index of fish
which_word_matched = match_obj.group() # "fish"
# Note, if no match, match_obj is None
UPDATE: Alcuni occorre prestare attenzione quando si combinano parole ad un singolo modello di parole alternative. Il codice seguente costruisce un'espressione regolare, ma escapes any regex special characters e ordina le parole in modo che le parole più lunghe hanno la possibilità di abbinare prima di qualsiasi prefissi più brevi della stessa parola:
def wordlist_to_regex(words):
escaped = map(re.escape, words)
combined = '|'.join(sorted(escaped, key=len, reverse=True))
return re.compile(combined)
>>> r.search('smash atomic particles').span()
(6, 10)
>>> r.search('visit usenet:comp.lang.python today').span()
(13, 29)
>>> r.search('a north\south division').span()
(2, 13)
>>> r.search('012cat').span()
(3, 6)
>>> r.search('0123dog789cat').span()
(4, 7)
FINE UPDATE
Dovrebbe si noti che si vorrà formare la regex (es. - chiama re.compile()) il meno possibile. Il miglior caso sarebbe sapere in anticipo quali sono le tue ricerche (o le calcoli una volta/di rado) e poi salvare il risultato di re.compile da qualche parte. Il mio esempio è solo una semplice funzione senza senso in modo da poter vedere l'uso della regex. Ci sono alcuni documenti più regex qui:
http://docs.python.org/library/re.html
Spero che questo aiuti.
UPDATE: Non sono sicuro di come Python implementa le espressioni regolari, ma per rispondere alla domanda di Rax circa se o non ci sono limitazioni di re.compile() (ad esempio, quante parole si può provare a " | "insieme per abbinare in una sola volta), e la quantità di tempo per eseguire compilare: nessuno di questi sembra essere un problema. Ho provato questo codice, che è abbastanza buono per convincermi. (Avrei potuto farlo meglio aggiungendo i tempi e riportando i risultati, così come lanciando la lista di parole in un set per garantire che non ci siano duplicati ... ma entrambi questi miglioramenti sembrano un eccesso). Questo codice funzionava praticamente istantaneamente e mi convinse che sono in grado di cercare 2000 parole (di dimensione 10), e che e di esse corrisponderanno in modo appropriato.Ecco il codice:
import random
import re
import string
import sys
def main(args):
words = []
letters_and_digits = "%s%s" % (string.letters, string.digits)
for i in range(2000):
chars = []
for j in range(10):
chars.append(random.choice(letters_and_digits))
words.append(("%s"*10) % tuple(chars))
search_for = re.compile("|".join(words))
first, middle, last = words[0], words[len(words)/2], words[-1]
search_string = "%s, %s, %s" % (last, middle, first)
match_obj = search_for.search(search_string)
if match_obj is None:
print "Ahhhg"
return
index = match_obj.start()
which = match_obj.group()
if index != 0:
print "ahhhg"
return
if words[-1] != which:
print "ahhg"
return
print "success!!! Generated 2000 random words, compiled re, and was able to perform matches."
if __name__ == "__main__":
main(sys.argv)
UPDATE: Va notato che l'ordine delle cose ORed insieme nella regex conta. Date un'occhiata al seguente test ispirato TZOTZIOY:
>>> search_str = "01catdog"
>>> test1 = re.compile("cat|catdog")
>>> match1 = test1.search(search_str)
>>> match1.group()
'cat'
>>> match1.start()
2
>>> test2 = re.compile("catdog|cat") # reverse order
>>> match2 = test2.search(search_str)
>>> match2.group()
'catdog'
>>> match2.start()
2
Ciò suggerisce le questioni di ordine: - /. Non sono sicuro di cosa significhi per l'applicazione di Rax, ma almeno il comportamento è noto.
UPDATE: ho postato this questions about the implementation of regular expressions in Python che si spera di darci qualche informazione sulle problemi rilevati con questa domanda.
L'elenco delle sottostringhe è costante? Ti sto chiedendo perché usare le soluzioni di tipo Regex di solito comportano alcune precomputazioni dell'espressione regolare (rsp l'elenco delle sottostringhe nel tuo caso). Questa precomputazione sarebbe stata ammortizzata per molte ricerche? – Accipitridae