tags:

views:

332

answers:

6

I've got a book on python recently and it's got a chapter on Regex, there's a section of code which I can't really understand. Can someone explain exactly what's going on here (this section is on Regex groups)?

>>> my_regex = r'(?P<zip>Zip:\s*\d\d\d\d\d)\s*(State:\s*\w\w)'
>>> addrs = "Zip: 10010 State: NY"
>>> y = re.search(my_regex, addrs)
>>> y.groupdict('zip')
{'zip': 'Zip: 10010'}
>>> y.group(2)
'State: NY'
+2  A: 

The search method will return an object containing the results of your regex pattern.

groupdict returns a dictionnary of groups where the keys are the name of the groups defined by (?P...). Here name is a name for the group.

group returns a list of groups that are matched. "State: NY" is your third group. The first is the entire string and the second is "Zip: 10010".

This was a relatively simple question by the way. I simply looked up the method documentation on google and found this page. Google is your friend.

tristan
+7  A: 

regex definition:

(?P<zip>...)

Creates a named group "zip"

Zip:\s*

Match "Zip:" and zero or more whitespace characters

\d

Match a digit

\w

Match a word character [A-Za-z0-9_]

y.groupdict('zip')

The groupdict method returns a dictionary with named groups as keys and their matches as values. In this case, the match for the "zip" group gets returned

y.group(2)

Return the match for the second group, which is a unnamed group "(...)"

Hope that helps.

SchaeferFFM
thanks, that was what I was looking for
A: 

The (?P<identifier>match) syntax is Python's way of implementing named capturing groups. That way, you can access what was matched by match using a name instead of just a sequential number.

Since the first set of parentheses is named zip, you can access its match using the match's groupdict method to get an {identifier: match} pair. Or you could use y.group('zip') if you're only interested in the match (which usually makes sense since you already know the identifier). You could also access the same match using its sequential number (1). The next match is unnamed, so the only way to access it is its number.

Tim Pietzcker
+1  A: 
# my_regex = r' <= this means that the string is a raw string, normally you'd need to use double backslashes
# ( ... ) this groups something
# ? this means that the previous bit was optional, why it's just after a group bracket I know not
# * this means "as many of as you can find"
# \s is whitespace
# \d is a digit, also works with [0-9]
# \w is an alphanumeric character
my_regex = r'(?P<zip>Zip:\s*\d\d\d\d\d)\s*(State:\s*\w\w)'
addrs = "Zip: 10010 State: NY"

# Runs the grep on the string
y = re.search(my_regex, addrs)
Teifion
A: 

Adding to previous answers: In my opinion you'd better choose one type of groups (named or unnamed) and stick with it. Normally I use named groups. For example:

>>> my_regex = r'(?P<zip>Zip:\s*\d\d\d\d\d)\s*(?P<state>State:\s*\w\w)'
>>> addrs = "Zip: 10010 State: NY"
>>> y = re.search(my_regex, addrs)
>>> print y.groupdict()
{'state': 'State: NY', 'zip': 'Zip: 10010'}
Federico Ramponi
A: 
Steve Losh