Как кратко описать несколько операторов регулярных выражений в Python - PullRequest
13 голосов
/ 28 февраля 2009

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

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.]

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

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

Ответы [ 7 ]

24 голосов
/ 28 февраля 2009

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

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

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')
13 голосов
/ 28 февраля 2009

Аналогичный вопрос в сентябре: Как вы переводите эту идиому регулярного выражения из 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
2 голосов
/ 02 марта 2009

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

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

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

1 голос
/ 28 февраля 2009

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

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
0 голосов
/ 29 мая 2011
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'
0 голосов
/ 28 февраля 2009

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

match = re.match('regex1', string)
if match:
    # do stuff
    return

match = re.match('regex2', string)
if match:
    # do stuff
    return
0 голосов
/ 28 февраля 2009

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

for regex in ('regex1', 'regex2', 'regex3', 'regex4'):
    match = re.match(regex, string)
    if match:
        # Manipulate match.group(n)
        return result
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...