Question

I'm trying to use the following code:

try:
    clean = filter(None, re.match(r'^(\S+) (.*?) (\S+)$', full).groups())
except TypeError:
    clean = ""

However I get the following traceback...

Traceback (most recent call last):
  File "test.py", line 116, in <module>
    clean = filter(None, re.match(r'^(\S+) (.*?) (\S+)$', full).groups())
AttributeError: 'NoneType' object has no attribute 'groups'

What is the correct exception / correct way around this problem?

Was it helpful?

Solution

re.match returns None if it cannot find a match. Probably the cleanest solution to this problem is to just do this:

# There is no need for the try/except anymore
match = re.match(r'^(\S+) (.*?) (\S+)$', full)
if match is not None:
    clean = filter(None, match.groups())
else:
    clean = ""

Note that you could also do if match:, but I personally like to do if match is not None: because it is clearer. "Explicit is better than implicit" remember. ;)

OTHER TIPS

Traceback (most recent call last):
  File "test.py", line 116, in <module>
    clean = filter(None, re.match(r'^(\S+) (.*?) (\S+)$', full).groups())
AttributeError: 'NoneType' object has no attribute 'groups'

It tells you what error is to handle: AttributeError

The, it is either:

try:
    clean = filter(None, re.match(r'^(\S+) (.*?) (\S+)$', full).groups())
except AttributeError:
    clean = ""

or

my_match = re.match(r'^(\S+) (.*?) (\S+)$', full)
my_match = ''
if my_match is not None:
     clean = my_match.groups()

Try this:

clean = ""
regex =  re.match(r'^(\S+) (.*?) (\S+)$', full)
if regex:
    clean = filter(None, regex.groups())

The problem is, re.match(r'^(\S+) (.*?) (\S+)$', full) returns a None if it does not find a match. Hence the error.

Note: You do not require a try..except if you handle it this way.

You need to add the AttributeError to your exception clause.

An except clause may name multiple exceptions as a parenthesized tuple:

try:
    clean = filter(None, re.match(r'^(\S+) (.*?) (\S+)$', full).groups())
except (TypeError, AttributeError):
    clean = ""

I think handling AttributeError using try, catch is a much cleaner solution. It may so happen that any transformation on performed the row may be a very expensive operation. For e.g.

match = re.match(r'^(\S+) (.*?) (\S+)$', full)

if match is not None: clean = filter(None, match.groups()) else: clean = ""

in the above case, the structure of the row changed in such a way that the regex delivered partial result. So, now match will not be none and the AttributeError exception will be thrown.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top