Choose Python function to call based on a regex Choose Python function to call based on a regex python python

Choose Python function to call based on a regex


This is based on Udi's nice answer.

I think that the difficulty of creating anonymous functions is a bit of a red herring. What you really want to do is to keep related code together, and make the code neat. So I think decorators may work for you.

import re# List of pairs (regexp, handler)handlers = []def handler_for(regexp):    """Declare a function as handler for a regular expression."""    def gethandler(f):        handlers.append((re.compile(regexp), f))        return f    return gethandler@handler_for(r'^<\w+> (.*)')def handle_message(msg):    print msg@handler_for(r'^\*{3} (.*)')def handle_warning(msg):    global num_warnings, num_fatals    num_warnings += 1    if is_fatal(msg):        num_fatals += 1


Nicer DRY way to solve your actual problem:

def message(msg):    print msgmessage.re = '^<\w+> (.*)'def warning(msg):    global num_warnings, num_fatals    num_warnings += 1    if ( is_fatal( msg ) ):        num_fatals += 1warning.re = '^\*{3} (.*)'handlers = [(re.compile(x.re), x) for x in [        message,        warning,        foo,        bar,        baz,    ]]


Continuing Gareth's clean approach with a modular self contained solution:

import re# in util.pyclass GenericLogProcessor(object):    def __init__(self):      self.handlers = [] # List of pairs (regexp, handler)    def register(self, regexp):        """Declare a function as handler for a regular expression."""        def gethandler(f):            self.handlers.append((re.compile(regexp), f))            return f        return gethandler    def process(self, file):        """Process a file line by line and execute all handlers by registered regular expressions"""        for line in file:            for regex, handler in self.handlers:                m = regex.search(line)                if (m):                  handler(m.group(1))      # in log_processor.pylog_processor = GenericLogProcessor()@log_processor.register(r'^<\w+> (.*)')def handle_message(msg):    print msg@log_processor.register(r'^\*{3} (.*)')def handle_warning(msg):    global num_warnings, num_fatals    num_warnings += 1    if is_fatal(msg):        num_fatals += 1# in your codewith open("1.log") as f:  log_processor.process(f)