Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Regular Expressions in Python Introduction to Regular Expressions Email Groups

My regex finds only first entry (stack with named groups)

If I add to my code print(contacts.groupdict()) I get only first line match {'phone': '555-555-5555', 'email': 'kenneth+challenge@teamtreehouse.com', 'name': 'Love, Kenneth', 'twitter': '@kennethlove'}

emails.py
import re

string = '''Love, Kenneth, kenneth+challenge@teamtreehouse.com, 555-555-5555, @kennethlove
Chalkley, Andrew, andrew@teamtreehouse.co.uk, 555-555-5556, @chalkers
McFarland, Dave, dave.mcfarland@teamtreehouse.com, 555-555-5557, @davemcfarland
Kesten, Joy, joy@teamtreehouse.com, 555-555-5558, @joykesten'''

contacts = re.search(r'''
    ^(?P<name>[\w]+,\s[\w]+),\s # Last and first names
    (?P<email>[\w+]+@[\w.]+),\s # Email
    (?P<phone>[\d]{3}-[\d]{3}-[\d]{4}),\s # Phone
    (?P<twitter>@[\w]+)$ # Twitter
''', string, re.X|re.M)

3 Answers

Stuart Wright
Stuart Wright
41,120 Points

You don't need to get the actual group, you just need to get the search object. The code for part 1 is simply:

contacts = re.search(r'''
    (?P<email>[\w+]+@[\w.]+),\s # Email
    (?P<phone>[\d]{3}-[\d]{3}-[\d]{4}),\s # Phone
''', string, re.X|re.M)

For part 2 you need to do something similar, but create a variable called twitters which searches for the Twitter handles.

Taylor Quinn
Taylor Quinn
20,003 Points

This works but I don't understand why. It does not catch the email dave.mcfarland@teamtreehouse.com. With (?P<email>[\w+]+@[\w.]+),\s you would end up with mcfarland@teamtreehouse.com not dave.mcfarland@teamtreehouse.com.

Stuart Wright
Stuart Wright
41,120 Points

That is what re.search() does - it searches for the first match only. What you need is re.findall() if you want to find all matches.

The challenge you have linked only requests you to use re.search() though, so presumably it's happy for you to only find the first person.

But re.M flag makes search to work on multiple lines, am I right?

Stuart Wright
Stuart Wright
41,120 Points

My understanding of re.M is that it allows you to match at the start of line rather than only start of string using the '^' character, but it still only returns one match if using re.search.

If you go to 8:30 in the preceding video, Kenneth confirms that his code (which is similar to the code in the challenge), will only return the first line.

How to complete this challenge? When I'm trying to use 'findall' method it returns a list of tuples like [('Kenneth', 'Love'), ...] and there is no method groupdict() like in re.search result object. I can't get named groups too in this case

Lauren Gainsbrook
Lauren Gainsbrook
12,539 Points

Like Stuart said, the re.M flag allows you to search each line individually, rather than searching the entire string at once.

I understand that if you use .groupdict(), re.search will return all the matching key/pair values in a dictionary (not just the first).

I'm still trying to figure this out, but it seems as though .search() should be used in conjunction with .groupdict()??