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 Players Dictionary and Class

Elizabeth McInerney
Elizabeth McInerney
3,175 Points

players

OK< you got me on that last line in string. I tried doing the re.search 3 different times, the first time to get the first 4 names and then a 2nd and 3rd time to read in the names in the last line. The first re worked as expected, the next 2 returned empty. Perhaps you can't read from a string more than 1 time? Anyway, I was hoping to do the 2nd two reads and then append the results to the first. Other than that idea, I can't figure out how to format this to read the last line at the same time I am reading the first 4 lines. Help!

players.py
import re

string = '''Love, Kenneth: 20
Chalkley, Andrew: 25
McFarland, Dave: 10
Kesten, Joy: 22
Stewart Pinchback, Pinckney Benton: 18'''

players = re.findall(r'^(?P<last_name>[\w]+),\s(?P<first_name>[\w]+): (?P<score>\d{2})$',string, re.M)

5 Answers

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,441 Points

You are actually very close.

What your rexep r'^(?P<last_name>[\w]+),\s(?P<first_name>[\w]+): (?P<score>\d{2})$' is saying:

from-line-beginning start-group-last_name start-set any-word-char end-set one-or-more-sets end-group-last_name comma white-space start-group-first_name start-set any-word-char end-set one-or-more-sets end-group-first_name colon space start-group-score two-digits end-group end-of-line

Isn't it obvious? :-P What your are missing is the possibility of spaces in the first and last name:

from-line-beginning start-group-last_name start-set any-word-char space end-set one-or-more-sets end-group-last_name comma white-space start-group-first_name start-set any-word-char space end-set one-or-more-sets end-group-first_name colon space start-group-score two-digits end-group end-of-line

The challenge also says to use a re.search() or re.match(). Since you've got the beginning ^ and the end $, I've changed the function to match().

Adding the missing spaces give you:

import re

string = '''Love, Kenneth: 20
Chalkley, Andrew: 25
McFarland, Dave: 10
Kesten, Joy: 22
Stewart Pinchback, Pinckney Benton: 18'''

players = re.match(r'^(?P<last_name>[\w ]+),\s(?P<first_name>[\w ]+): (?P<score>\d{2})$',string, re.M)
Elizabeth McInerney
Elizabeth McInerney
3,175 Points

Are you saying that Stewart Pinchback is a last name and Pinckney Benton is a first name, and he has 18 points? I thought that was 2 guys, Stewart and Pinckney (first names) both with 18 points.

Chris Freeman
Chris Freeman
Treehouse Moderator 68,441 Points

Yes. One person with a complex name. Or at least that is how the grader is viewing it.

To parse as two people is possible using group references (like \1) but it's beyond the question scope.

Elizabeth McInerney
Elizabeth McInerney
3,175 Points

Also, I am not clear on why using ^$ would affect your choice of re.match vs re.findall. I guess I think of match and search as operating on one line and findall as operating on something that is longer than one line.

Chris Freeman
Chris Freeman
Treehouse Moderator 68,441 Points

re.findall returns a list whereas re.search and re.match return a MatchObject instance as discribed in the docs

Elizabeth McInerney
Elizabeth McInerney
3,175 Points

So I played around with everything in workspaces. I see that match/seach both return a MatchObject and findall returns a list. I also see that groupdict() and group(0) don't work on findall. This has me wondering if you would ever be in a situation to use group(1) or group(2) etc with a MatchObject from match/search. I also see that including ^$re.M makes no difference on any of the outcomes with match/search/findall. Is that because the info for each person is limited to 1 line. If things wrapped around to a second line, then I am guessing you would need ^$re.M, correct?

Chris Freeman
Chris Freeman
Treehouse Moderator 68,441 Points

Correct. Search, match, and findall each have their uses. Getting a matchobject with all it's methods including group, groups, groupdict can be exactly want is needed in some coding situations.

Elizabeth McInerney
Elizabeth McInerney
3,175 Points

Are ^$re.M always used together? On another question called twitters, a person named ilikepython responded with a suggestion that I use $re.M together without the ^. I tried it and it did not work. Perhaps they just forgot to type in the ^. So issue 1 is how to get it to work, but issue 2 is understanding if there are situations when one uses 1 or 2 of the 3 items in ^$re.M

Chris Freeman
Chris Freeman
Treehouse Moderator 68,441 Points

Using the regex anchors ^ (beginning) and $ (end) may be used independently of the switch re.M.

The anchors are used to specify when a patch absolutely much match all the way to the end points.

The switch indicates that you want to repeat the pattern match anew when a line break is detected in the input string.

Elizabeth McInerney
Elizabeth McInerney
3,175 Points

OK, so if I use 'some pattern$', that means look for the pattern at the end of the line. If I use '^some pattern$', that means I only return an answer if the pattern matches all the way from the beginning to the end. And re.M handles doing this across multiple lines? So I guess you don't need just ^ alone because match will look for something at the beginning of a line.

Chris Freeman
Chris Freeman
Treehouse Moderator 68,441 Points

Using the beginning or ending markers will limit to search or match to returning either one or none items per line. With match, the regex consumes the whole line so the anchors for beginning and end are useful indicators that the pattern goes all the way from end to end.

Needing to use re.M depends on how your date it is structure:. Is it one long string or stream of characters Or is it a list or other iterable.

Chris Freeman
Chris Freeman
Treehouse Moderator 68,441 Points

There is another case where the beginning and end markers are very useful. If your match expression ends with a wildcard such as then you need the ending anchor to force it to include everything all the way to the end.

If your pattern ended with an obvious hardcoded character than that would act as your ending marker it's making the beginning and ending marker redundant.

Elizabeth McInerney
Elizabeth McInerney
3,175 Points

Interesting, and good point about the data sometimes having it's own markers. That's true, thanks!

Elizabeth McInerney
Elizabeth McInerney
3,175 Points

Well thanks, that makes it a LOT easier! I think Treehouse should change the last line. Give the last name a hyphen, and the first name something like Stewart James. Unless that is a character in a book or something and I am the only one just not getting the joke.

Elizabeth McInerney
Elizabeth McInerney
3,175 Points

So chris freeman, the difference between findall and seach/match is not how far along the string it looks, but what it returns? I need to go to workspaces and print each out and look at the differences.