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 trialMary Yang
1,769 PointsPython Regular Expressions - Display all numbers except 567
Hi, I've been searching the internet, checking the Python documentation, and watching the video and I can't figure out how to do this. I've tried several times, but I can't get it to work.
How do I display all the numbers in the string except for 567?
import re
string = '1234567890'
def good_numbers():
return re.findall(r'[\d]*[^567]', string)
11 Answers
Kenneth Love
Treehouse Guest TeacherRemember, the challenge wants you to make sure you don't have 5, 6, or 7 in the match. Don't worry about anything else, just keep those items out.
Ary de Oliveira
28,298 PointsChallenge Task 1 of 1 repost correta
Create a variable named good_numbers that is an re.findall() where the pattern matches anything in string except the
numbers 5, 6, and 7.
import re
string = '1234567890'
good_numbers = re.findall(r'[^567]', string)
Keep going to meet your Goal Ary.
Vittorio Somaschini
33,371 PointsHello Mary!
First thing I have noticed is that you don't have to set up a function here as the challenge only requests a variable. So the last line would be:
good_numbers = {some code here}
The code that goes there has to find all the numbers in the string (d[,9]), apart from 567 and you had this right.
So, final code would be:
good_numbers = re.findall(r'\d[,9][^567]', string)
Hope that helps, if unclear please ask
Vittorio
Mary Yang
1,769 PointsHi Vittorio,
Thanks for taking the time to look into this. You're correct. The only issue was that I was creating a function instead of a simple variable. I just input it and it worked. Crazy how after awhile I can miss the most basic things like this.
Thanks again for your help!
Dan A
Courses Plus Student 4,036 PointsThe match object for your pattern is ['890']. This answer, however, is accepted by the CC. The correct answer should result in ['1234890'], right?
Mary Yang
1,769 PointsHi Dan A, yes it should be ['1234890']. If my code is outputting the wrong list, how come it was accepted? How should the correct code be written? I'm really struggling with some of these regex challenges.
Mary Yang
1,769 PointsKenneth Love, can you provide any feedback on how to get the correct answer? I've been combing over the python documentation, checking stack overflow, and have re-created the code about 1000 times in a workspace file I made for test code.
I'm having a very difficult time with the regex stuff. I understand it perfectly when you are talking about it, but when I try to make groups, I seem to always be grabbing all the text, none of the text, or the text isn't split into the proper groups.
This has by far been the hardest part of the Python track for me. I feel like I understand the material until I try to implement it for the tests and I bomb. I haven't passed 3 out of the last four coding challenges.
Dan A
Courses Plus Student 4,036 PointsMary, I still can't figure this one out as well!
dinesh seyyadri
10,919 Pointsmy answer : good_numbers = re.findall(r'[0123489]',string)
Vittorio Somaschini
33,371 Pointsahahah
Kevin, could you please tell me what happens precisely if I pass in this?
good_numbers = re.findall(r'\d*[^567]', string)
Because it was my first try for this exercise and good numbers comes out like this ['1234567890'], so it gives back all the numbers. I would like to know precisely what the compiler does.
TY
Vittorio
Kenneth Love
Treehouse Guest TeacherI'll guess that by "Kevin" you mean "Kenneth". :D
So what does r'\d*[^567]'
match? First, it matches an infinite number of numbers, so the entire string would be matched. Then, once it hits infinity (or something that isn't a number), it'll exclude 5, 6, and 7. You really have to be careful with *
.
Vittorio Somaschini
33,371 PointsOOps so sorry about that...
It looks like someone needs a break!!
ty Kenneth.
BTW that gif is awesome!!
james white
78,399 PointsSince this is the only forum thread that deals with the excluded (or negated) numbers 567 challenge
I just wanted to noted the exact word challenge (for the spidering/crawling of search engines):
"Create a variable named good_numbers that is an re.findall() where the pattern matches anything in string except the numbers 5, 6, and 7."
..as well as the link to the challenge:
//*******************************************************
Note: I didn't find anything in the address_book.py zipped file (that you can download for this course)
which has any sort of line of code that could server as a good pattern example
of using the exclude character (the caret ^) by itself in a re.final() context to exclude a set (or subset) of numbers (or numbers as a set of string characters) :
import re
names_file = open("names.txt", encoding="utf-8")
data = names_file.read()
names_file.close()
#print(re.match(r'Love', data))
#print(re.search(r'Kenneth', data))
#print(re.findall(r'\(?\d{3}\)?-?\s?\d{3}-\d{4}', data))
#print(re.findall(r'\w*, \w+', data))
#print(re.findall(r'[-\w\d+.]+@[-\w\d.]+', data))
#print(re.findall(r'\b[trehous]{9}\b', data, re.I))
#print(re.findall(r'''
# \b@[-\w\d.]* # First a word boundary, an @, and then any number of characters
# [^gov\t]+ # Ignore 1+ instances of the letters 'g', 'o', or 'v' and a tab.
# \b # Match another word boundary
#''', data, re.VERBOSE|re.I))
#print(re.findall(r"""
# \b[-\w]+, # Find a word boundary, 1+ hyphens or characters, and a comma
# \s # Find 1 whitespace
# [-\w ]+ # 1+ hyphens and characters and explicit spaces
# [^\t\n] # Ignore tabs and newlines
#""", data, re.X))
line = re.compile(r'''
^(?P<name>(?P<last>[-\w ]*),\s(?P<first>[-\w ]+))\t # Last and first names
(?P<email>[-\w\d.+]+@[-\w\d.]+)\t # Email
(?P<phone>\(?\d{3}\)?-?\s?\d{3}-\d{4})?\t # Phone
(?P<job>[\w\s]+,\s[\w\s.]+)\t? # Job and company
(?P<twitter>@[\w\d]+)?$ # Twitter
''', re.X|re.M)
#print(line.search(data).groupdict())
for match in line.finditer(data):
print('{first} {last} <{email}>'.format(**match.groupdict()))
Watching the video many many times wasn't very helpful either.
Personally I would think about adding a 'hint' to the challenge question about needing to use a ^ symbol in the answer (just for the 'slow to catch on' people like me).
Kenneth Love
Treehouse Guest TeacherThe challenge is directly after the video where we talk about nothing new other than creating a negated set. Sure, I can add a ^
hint, but that's basically handing you the answer.
As for the example code, line 15 of your above snippet has a negated set. The very one, in fact, that we used in the video just prior to this CC to stop catching the letters 'g', 'o', and 'v' in an email address' domain.
Philip Ondrejack
4,287 PointsI'm curious as to why this didn't work, and many variations of it...
good_numbers = re.findall(r'\d[^567]', string)
Everything that kept outputting had - what I want to call a - "ghost" 7 in it. No matter what everything kept sliding down one or rearranging. I could get 5,6 to disappear easily but not the 7.
@KennethLove -- your code did work the good_numbers = re.findall(r'[^567]', string)
. But why not with \d?
Kenneth Love
Treehouse Guest Teacherr'\d[^567]'
says "find any digit, and then anything that isn't 5, 6, or 7. That first \d
is what'll catch random ghost 7s.
Mason Preusser
2,279 PointsWould you mind explaining why that is?
Mateo Marin
9,559 Points>>> string = '1234567890'
>>> print(re.findall(r'[ˆ567]', string))
['5', '6', '7']
>>> print(re.findall(r'\d[ˆ567]', string))
['45', '67']
Kenneth Love, still don't get why I get these answers, they don't make much sense when compared to what we learned on the videos. Any hints? Thanks!
Kenneth Love
Treehouse Guest TeacherI don't get those results.
>>> string
'1234567890'
>>> re.findall(r'[^567]', string)
['1', '2', '3', '4', '8', '9', '0']
>>> re.findall(r'\d[^567]', string)
['12', '34', '78', '90']
Wei Shih
4,247 PointsHi Kenneth Love, could you explain why I get this result?
>>> string = '1234567890'
>>> print(re.findall(r'\d{1}', string))
['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']
>>> print(re.findall(r'\d{1}[^567]', string))
['12', '34', '78', '90']
I expect the second statement will give me the correct answer. (as it should remove '5', '6', '7' from the first statement's result) Thanks!
Kenneth Love
Treehouse Guest TeacherRegular expressions are very literal. Look at your pattern \d{1}[^567]
. That pattern says there will be two elements: a number that is one character long, and another element that's not 5, 6, or 7.
That's why you get '78'
in your matches. 7
is definitely a single digit.
Wei Shih
4,247 PointsOh, I see!
I just ignored that [^567] still represents another digit. Thanks Kenneth!
Piotr Manczak
Front End Web Development Techdegree Graduate 29,363 Pointsgood_numbers = "".join(re.findall(r"[^567]", string))
It is working for some reason. Why? I don't know. This is all weird and twisted. r"[^567]", string returns [1, 2, 3, 4, 8, 9, 0]
Mary Yang
1,769 PointsMary Yang
1,769 PointsKenneth Love I understand the question, I just don't know how to keep those out and return everything else. When I try I get the last few digits or I get none. I have yet to find an answer anywhere. Can you provide more insight please? I'm sure I could do it using a loop, but that would defeat the point of using regex, right?
Kenneth Love
Treehouse Guest TeacherKenneth Love
Treehouse Guest TeacherI can almost guarantee you're overthinking this. I know I did when I first wrote it. All you need to do is exclude those three characters. How do you exclude characters in regex? No loops required. Your pattern will be like 6 characters long.
Mary Yang
1,769 PointsMary Yang
1,769 Points[^567] returns only 1-4, not '123489'. I've tried about a 1000 variations of that adding groups, adding stuff like \d, \w, \d. to the front, back, to it's own group, Combinations like [^5-7]\d don't work, neither does stuff like \d.[^567]\d+. I've tried every combination of +.*? I can think of. I'm at a loss. I'm doing another tutorial on regex right now hoping to find a solution, but it's not covering how to exclude stuff in the middle of a string, only how to exclude stuff at the beginning or end. I'm about to give up and just ask on stack overflow. :(
edit: I know I can define two variables, one to grab 1-4, and another to grab 8-9 and then join the two strings together to get the final string, but I'm almost positive that's not the answer you're looking for. It seems too convoluted based on the videos.
edit again: OK, I think it has something to do with non-capturing groups? I don't believe we covered this in the videos. Based on what I've read, \d+(?:567)? should work, right? It's still printing out 567 though.
Kenneth Love
Treehouse Guest TeacherKenneth Love
Treehouse Guest TeacherCan you show me exactly what you're trying? I just passed it with this:
good_numbers = re.findall(r'[^567]', string)
and with:
good_numbers = re.findall(r'[^5-7]', string)
Mary Yang
1,769 PointsMary Yang
1,769 PointsMrglglrglglglglglglgl!!!!!!
I was using match and search! /wrists.
I had passed the test back when it accepted my incorrect answer. I've since been trying to get the right answer in workspaces in a tests.py file I made. Somewhere along the way I guess I changed findall to search and then match. OMG these things!
Thank you so much for your help. I was about to throw my computer into the oven and set it to broil.
Kenneth Love
Treehouse Guest TeacherKenneth Love
Treehouse Guest TeacherAbsolutely nothing in the history of programming is responsible for more broiled computers than regular expressions.