tags:

views:

228

answers:

6

I have two variables that are the result of regex searches.

a = re.search('some regex', str)
b = re.search('different regex', str)

This should return a re object. If they are not None, I want to use the group() method to get the string that it matched. This is the code I am using right now to do this:

if a != None:
   a = a.group()
if b != None:
   b = b.group()

Is there a more clever way to write these two if-statements? Maybe combine them into one? I think taking up 4 lines to do this is too verbose.

Thanks.

+4  A: 

Don't shadow the built-in str, and say

if a:

instead of

if a != None

Not much else to improve imho.

jellybean
+2  A: 

If you really must have a one-liner:

a, b = a.group() if a else None, b.group() if b else None
tzaman
+4  A: 

a = a.group() if a else None

Yassin
+1  A: 

wrap it in a function

def generic_group(x)
    if x != None:
        x = x.group()
itsmyown
Your function doesn't return anything and so has no effect.
Daenyth
In Python, all variables are passed by reference. You don't have to return anything to change non-local value.
itsmyown
Sort of. The 'x' is a name that refers to an object, which at the start of the function is indeed the same as it was outside the function. Unfortunately you then go on to reseating the reference and point the local 'x' name to x.group(), which has no effect outside the function. Assignment in Python is rebinding a name, not a mutating operation as it is in C++.
Kylotan
@Kylotan: Thank you for the clarification.
itsmyown
A: 

You can refactor little:

a, b = (var.group() if var is not None else None for var in (a,b) )

This keeps value of a if it is for example 0. This is the end of your request.

However after some time passed I came up with this suggestion considering context:

import re
target = """"Id","File","Easting","Northing","Alt","Omega","Phi","Kappa","Photo","Roll","Line","Roll_line","Orient","Camera"
1800,2008308_017_079.tif,530658.110,5005704.180,2031.100000,0.351440,-0.053710,0.086470,79,2008308,17,308_17,rightX,Jen73900229d
"""
print target
regs=(',(.*.tif)',',(left.*)',',(right.*)')
re_results=(result.group()
            for result in ((re.search(reg, target)
                            for reg in regs)
                           )
            if result is not None)
print list(re_results)
Tony Veijalainen
+1  A: 

As I commented, I prefer not to reuse a and b for both the Match object and the matched text. I'd go with a function to pull out the match, like this:

>>> def text_or_none(v): return v.group() if v is not None else None
>>> a = text_or_none(re.search("\d", "foo"))
None
>>> b = text_or_none(re.search("\w+", "foo"))
foo
Stephen