2010-06-14 10 views
37

Mam listę wyrażeń regularnych w python i ciąg znaków. Czy istnieje elegancki sposób sprawdzenia, czy co najmniej jedno wyrażenie regularne na liście pasuje do ciągu? Przez elegancki mam na myśli coś lepszego niż po prostu przechodzenie przez wszystkie wyrażenia regularne i sprawdzanie ich w stosunku do łańcucha znaków i zatrzymywanie, jeśli znaleziono dopasowanie.Python: Elegancki sposób sprawdzenia, czy co najmniej jeden regex na liście pasuje do ciągu znaków

Zasadniczo miałem ten kod:

list = ['something','another','thing','hello'] 
string = 'hi' 
if string in list: 
    pass # do something 
else: 
    pass # do something else 

teraz chciałbym mieć kilka wyrażeń regularnych na liście, a nie tylko strun, a ja zastanawiałem się, czy nie jest to eleganckie rozwiązanie do sprawdzenia dla dopasuj, aby zastąpić if string in list:.

Z góry dziękuję.

+0

pyton nie ma nic, że robi Emacs LISP na regexp-opt https://www.gnu.org/software/emacs/manual/html_node/elisp/Regexp -Functions.html – ggg

+0

Dlaczego nie lubisz pętli? –

Odpowiedz

65
import re 

regexes = [ 
    "foo.*", 
    "bar.*", 
    "qu*x" 
    ] 

# Make a regex that matches if any of our regexes match. 
combined = "(" + ")|(".join(regexes) + ")" 

if re.match(combined, mystring): 
    print "Some regex matched!" 
+3

Jeśli nie musisz wiedzieć, który z nich pasuje, lepiej jest zamieniać je na '(?: Regex)' zamiast '(regex)' –

+2

Ta metoda nie działa, jeśli w macierzy znajduje się więcej niż 100 wyrażeń regularnych (Python 2.6). Spróbuj odpowiedzi nosklo poniżej. – Amjith

+3

'regexes = '(?:% S)'% '|' .join (regexes)' – alxndr

72
import re 

regexes = [ 
    # your regexes here 
    re.compile('hi'), 
# re.compile(...), 
# re.compile(...), 
# re.compile(...), 
] 

mystring = 'hi' 

if any(regex.match(mystring) for regex in regexes): 
    print 'Some regex matched!' 
+0

Jeśli pracujesz w Pythonie 2.4, nie będziesz miał żadnego "-" zobacz http://stackoverflow.com/questions/3785433/python-backports-for-some-methods –

+1

Jak to jest * "coś lepszego niż po prostu zapętlenie wszystkie wyrażenia regularne i sprawdzanie ich w łańcuchu i zatrzymywanie, jeśli znaleziono dopasowanie "*? Sądzę, że kombinacja Neda i tej odpowiedzi mogłaby być zwycięzcą ... – johndodo

2

Mieszanka zarówno Ned i odpowiedzi Nosklo użytkownika. Prace gwarantowane przez dłuższy lista ... nadzieję, że

import re 
raw_lst = ["foo.*", 
      "bar.*", 
      "(Spam.{0,3}){1,3}"] 

reg_lst = [] 
for raw_regex in raw_lst: 
    reg_lst.append(re.compile(raw_regex)) 

mystring = "Spam, Spam, Spam!" 
if any(compiled_reg.match(mystring) for compiled_reg in reg_lst): 
    print("something matched") 
Powiązane problemy