regexps: testing and creating MatchObjects in one fell swoop

Alex Martelli aleaxit at yahoo.com
Fri Sep 8 12:40:03 EDT 2000


"Dan Schmidt" <dfan at harmonixmusic.com> wrote in message
news:wku2bqj2k6.fsf at turangalila.harmonixmusic.com...
    [snip]
> I'd love to be able to write something like (and I know I can't):
>
>   if (match = re.search (r"(\d+)\s+(\d+)", line)):
>       (num1, num2) = match.groups()

[warning -- haven't tested the following code, so it might
have a typo or three, but the general ideas are OK:-)]

I think you can come reasonably close, if you insist; e.g:

def match_ok(the_re, the_line, the_groups):
    match = re.search(the_re, the_line)
    if match: the_groups.extend(match.groups())
    return match

results = []

if match_ok(r"(\d+)\s+(\d+)", line, results):
    num1, num2 = results
elif match_ok(r"(\w+)\s+(\w+)\s+(\w+)", line, results):
    word1, word2, word3 = results

and so on.

Basically, to get this style you must use a function,
to which you pass a mutable object; the function can
mutate that object as a side effect of success.

An alternative is to use a class instead to carry
the state around, e.g., if your typical case is doing
many matches on a single line, something like:

class rese:
    def __init__(self, line=None):
        self.line=line
        self.match=None
    def search(self, the_re, line=None):
        if not line: line=self.line
        self.match=re.search(the_re, line)
        return self.match
    def groups(self):
        if self.match: return self.groups

Usage would be:

matcher = rese(line)

if matcher.search(r"(\d+)\s+(\d+)"):
    num1, num2 = matcher.groups()
elif matcher.search(r"(\w+)\s+(\w+)\s+(\w+)"):
    word1, word2, word3 = matcher.groups()

Slightly more once-off work (to define the class; note
that the one I've defined is a bit more general than
what I'm actually using!), somewhat more elegant and
handy in use.  Besides, side effects are more expected
on a class's state than on a function's argument (even
a mutable one), I think, so this may be clearer to
some reader in the future (opinable, I guess).


Alex






More information about the Python-list mailing list