best way to do a series of regexp checks with groups

Alex Martelli aleaxit at yahoo.com
Mon Jan 24 03:38:25 EST 2005


Nick Craig-Wood <nick at craig-wood.com> wrote:

> Here is a different solution...
> 
> class Result:
>     def set(self, value):
>         self.value = value
>         return value
> 
> m = Result()
> 
> if m.set(re.search(r'add (\d+) (\d+)', line)):
>     do_add(m.value.group(1), m.value.group(2))
> elif m.set(re.search(r'mult (\d+) (\d+)', line)):
>     do_mult(m.value.group(1), m.value.group(2))
> elif m.set(re.search(r'help (\w+)', line)):
>     show_help(m.value.group(1))

This is roughly the same as my Cookbook recipe for test-and-set, but if
all you're using it for is RE search and MO access you might be better
off giving more responsibilities to your auxiliary class, such as:

class ReWithMemory(object):
    def search(self, are, aline):
        self.mo = re.search(are, aline)
        return self.mo
    def group(self, n):
        return self.mo.group(n)

m = ReWithMemory()

if m.search(r'add (\d+) (\d+)', line):
    do_add(m.group(1), m.group(2))
elif m.search(r'mult (\d+) (\d+)', line):
    do_mult(m.group(1), m.group(2))
elif m.search(r'help (\w+)', line):
    show_help(m.group(1))

Demeter's Law suggests that the 'm.value.group' accesses in your
approach are better handled by having m delegate to its `value'; and the
repeated m.set(re.search( ... seem to be a slight code smell, violating
"once and only once", which suggests merging into a single `set' method.
Your approach is more general, of course.


Alex



More information about the Python-list mailing list