best way to do a series of regexp checks with groups

Duncan Booth duncan.booth at invalid.invalid
Mon Jan 24 10:02:27 CET 2005


Mark Fanty wrote:

> No nesting, but the while is misleading since I'm not looping and this
> is a bit awkward.  I don't mind a few more key strokes, but I'd like
> clarity.  I wish I could do
> 
> if m =  re.search(r'add (\d+) (\d+)', $line):
>     do_add(m.group(1), m.group(2))
> elif m = re.search(r'mult (\d+) (\d+)', $line):
>     do_mult(m.group(1), m.group(2))
> else m = re.search(r'help (\w+)', $line):
>     show_help(m.group(1))
> 
> Now that's what I'm looking for, but I can't put the assignment in an 
> expression.  Any recommendations?  Less "tricky" is better. 

Try thinking along the following lines. It is longer, but clearer and 
easily extended to more commands. For more complete command processing use 
the 'cmd' module.

import sys

class Command:
    def do_add(self, a, b):
        '''add <number> <number>'''
        return int(a)+int(b)

    def do_mult(self, a, b):
        '''mult <number> <number>'''
        return int(a)*int(b)

    def do_help(self, *what):
        '''help [words] - give some help'''
        if not what:
            what = sorted(s[3:] for s in dir(self) if s.startswith('do_'))
        def error(): '''Unknown command'''
        for w in what:
            cmd = getattr(self, 'do_'+w, error)
            print "Help for %r:\n%s\n" % (w, cmd.__doc__)
    
    def do_exit(self):
        '''exit - the program'''
        sys.exit(0)

    def __call__(self, line):
        words = line.split()
        if not words:
            return
        command = words.pop(0)
        cmdfn = getattr(self, 'do_'+command, None)
        if not cmdfn:
            print "Unknown command %r. Use 'help' for help" % command
            return

        result = None
        try:
            result = cmdfn(*words)
        except TypeError, msg:
            print msg
        if result is not None:
            print "result is",result

cmd = Command()

while 1:
    cmd(sys.stdin.readline())



More information about the Python-list mailing list