Reputation: 3555
I need to do re.match sequentially, and in match case I need result of match to optain groups. Now I can do next:
r = re.match('cond1', l)
if r:
# work with r.group()
else:
r = re.match('cond2', l)
if r:
# work with r.group()
else:
r = re.match('cond3', l)
if r:
# work with r.group()
etc. But how can I do better? I see it is not possible to perform assignment in if like this:
if r = re.match('cond1', l):
# work with r.group()
elif r = re.match('cond2', l):
# work with r.group()
elif r = re.match('cond3', l)
# work with r.group()
Upvotes: 0
Views: 60
Reputation: 59112
You could use a comprehension:
r, cond = next((m,c) for (m,c) in ((re.match(cond, line), cond) for cond in ('cond1', 'cond2', 'cond3')) if m)
if cond=='cond1':
# work with r.group() for cond1
elif cond=='cond2':
# work with r.group() for cond2
Or if that looks too arcane, a loop:
for cond in ('cond1', 'cond2', 'cond3'):
r = re.match(cond, line)
if r:
break
if not r:
# no match
elif cond=='cond1':
# work with r.group() for cond1
elif cond=='cond2':
# work with r.group() for cond2
Upvotes: 3
Reputation: 365767
First, it often helps to refactor things out into functions. In this case, it helps because you can easily return early from a function; you can't return early from a block of code in the middle of other code.
def first_match(haystack):
r = re.match('cond1', haystack)
if r:
# work with r.group()
return
r = re.match('cond2', l)
if r:
# work with r.group()
return
r = re.match('cond3', l)
if r:
# work with r.group()
All the else
bits and indentation headaches go away.
Also, in general, when you're asking how to chain 3 or more things together, the right answer is to figure out how to chain any arbitrary number of things together, and just do that with N=3. Which usually means a loop (or a loop hidden inside a function like map
, or a recursive function definition, etc.). For example:
def first_match(exprs, haystack):
for expr in exprs:
r = re.match(expr, haystack)
if r:
return r
In this case, however, what you're trying to do is actually doable. Maybe not a good idea, but… A regex match
object is always truthy. And of course None
is falsey. So:
r = re.match('cond1', l) or re.match('cond2', l) or re.match('cond3', l)
if r:
# work with r.group(), which is the group for whichever matched
But notice that if you want to use the truthiness, you can do that in a loop too:
next(filter(bool, (re.match(cond, l) for cond in ('cond1', 'cond2', 'cond3'))))
Finally, you're already using regular expressions, so why not use regular expressions?
r = re.match('cond[123]', l)
if r:
# work with r.group()
Upvotes: 1