Multiple regex match idiom

Nick Vatamaniuc vatamane at gmail.com
Wed May 9 06:04:09 EDT 2007


On May 9, 5:00 am, Hrvoje Niksic <hnik... at xemacs.org> wrote:
> I often have the need to match multiple regexes against a single
> string, typically a line of input, like this:
>
> if (matchobj = re1.match(line)):
>   ... re1 matched; do something with matchobj ...
> elif (matchobj = re2.match(line)):


>   ... re2 matched; do something with matchobj ...
> elif (matchobj = re3.match(line)):
> ....
>
> Of course, that doesn't work as written because Python's assignments
> are statements rather than expressions.  The obvious rewrite results
> in deeply nested if's:
>
> matchobj = re1.match(line)
> if matchobj:
>   ... re1 matched; do something with matchobj ...
> else:
>   matchobj = re2.match(line)
>   if matchobj:
>     ... re2 matched; do something with matchobj ...
>   else:
>     matchobj = re3.match(line)
>     if matchobj:
>       ...
>
> Normally I have nothing against nested ifs, but in this case the deep
> nesting unnecessarily complicates the code without providing
> additional value -- the logic is still exactly equivalent to the
> if/elif/elif/... shown above.
>
> There are ways to work around the problem, for example by writing a
> utility predicate that passes the match object as a side effect, but
> that feels somewhat non-standard.  I'd like to know if there is a
> Python idiom that I'm missing.  What would be the Pythonic way to
> write the above code?

Hrvoje,

To make it more elegant I would do this:

1. Put all the ...do somethings... in functions like
re1_do_something(), re2_do_something(),...

2. Create a list of pairs of (re,func) in other words:
dispatch=[ (re1, re1_do_something), (re2, re2_do_something), ... ]

3. Then do:
for regex,func in dispatch:
    if regex.match(line):
          func(...)


Hope this helps,
-Nick Vatamaniuc






More information about the Python-list mailing list