Как сжато каскадировать несколько операторов regex в Python

Моя дилемма: я передаю свою функцию строку, в которой мне нужно выполнить многочисленные манипуляции с регулярными выражениями. Логика – это совпадение в первом регулярном выражении, сделать одно. Если нет совпадения, проверьте совпадение со вторым и сделайте что-нибудь еще, если не проверьте третий, и так далее. Я мог бы сделать что-то вроде этого:

if re.match('regex1', string): match = re.match('regex1', string) # Manipulate match.group(n) and return elif re.match('regex2', string): match = re.match('regex2', string) # Do second manipulation [etc.] 

Однако это кажется излишне подробным, и обычно, когда это так, это означает, что есть лучший способ, с которым я либо обозреваюсь, либо еще не знаю.

  • Длина самого длинного слова в списке
  • Есть ли у кого-нибудь предложение для лучшего способа сделать это (лучше с точки зрения внешнего вида кода, точки использования памяти или того и другого)?

  • быстрый python numpy, где функциональность?
  • python Вызов внешней программы приводит к ошибке % 1 не является допустимым приложением Win32
  • специфичная для платформы семантика Unicode в Python 2.7
  • Как правильно проверить покрытие с помощью Django + Nose
  • Django Tastypie не обновляет ресурс с помощью ManyToManyField
  • Монитор сетевого трафика с pcapy в python
  • 7 Solutions collect form web for “Как сжато каскадировать несколько операторов regex в Python”

    Аналогичный вопрос с конца сентября: как вы переводите эту идиому регулярного выражения из Perl в Python?

    Использование глобальных переменных в модуле, возможно, не лучший способ сделать это, но преобразование его в класс:

     import re class Re(object): def __init__(self): self.last_match = None def match(self,pattern,text): self.last_match = re.match(pattern,text) return self.last_match def search(self,pattern,text): self.last_match = re.search(pattern,text) return self.last_match gre = Re() if gre.match(r'foo',text): # do something with gre.last_match elif gre.match(r'bar',text): # do something with gre.last_match else: # do something else 

    Вообще говоря, в таких ситуациях вы хотите сделать код «управляемым данными». То есть, поместите важную информацию в контейнер и пропустите ее.

    В вашем случае важная информация (пары, функции).

     import re def fun1(): print('fun1') def fun2(): print('fun2') def fun3(): print('fun3') regex_handlers = [ (r'regex1', fun1), (r'regex2', fun2), (r'regex3', fun3) ] def example(string): for regex, fun in regex_handlers: if re.match(regex, string): fun() # call the function break example('regex2') 

    У меня была такая же проблема, как у вас. Вот мое решение:

     import re regexp = { 'key1': re.compile(r'regexp1'), 'key2': re.compile(r'regexp2'), 'key3': re.compile(r'regexp3'), # ... } def test_all_regexp(string): for key, pattern in regexp.items(): m = pattern.match(string) if m: # do what you want break 

    Это немного измененное решение из ответа Extracting info из больших структурированных текстовых файлов

    Хм … вы могли бы что-то использовать with конструкцией … um

     class rewrapper() def __init__(self, pattern, target): something def __enter__(self): something def __exit__(self): something with rewrapper("regex1", string) as match: etc with rewrapper("regex2", string) as match: and so forth 

    Являются ли манипуляции для каждого регулярного выражения похожими? Если да, попробуйте следующее:

     for regex in ('regex1', 'regex2', 'regex3', 'regex4'): match = re.match(regex, string) if match: # Manipulate match.group(n) return result 

    Здесь ваши регулярные выражения и совпадения не повторяются дважды:

     match = re.match('regex1', string) if match: # do stuff return match = re.match('regex2', string) if match: # do stuff return 
     class RegexStore(object): _searches = None def __init__(self, pat_list): # build RegEx searches self._searches = [(name,re.compile(pat, re.VERBOSE)) for name,pat in pat_list] def match( self, text ): match_all = ((x,y.match(text)) for x,y in self._searches) try: return ifilter(op.itemgetter(1), match_all).next() except StopIteration, e: # instead of 'name', in first arg, return bad 'text' line return (text,None) 

    Вы можете использовать этот класс следующим образом:

     rs = RegexStore( (('pat1', r'.*STRING1.*'), ('pat2', r'.*STRING2.*')) ) name,match = rs.match( "MY SAMPLE STRING1" ) if name == 'pat1': print 'found pat1' elif name == 'pat2': print 'found pat2' 
    Python - лучший язык программирования в мире.