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 Negated Numbers

Andy McDonald
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Andy McDonald
Python Development Techdegree Graduate 13,801 Points

Trouble negating numbers from a string

import re

string = '1234567890'

def good_numbers(stri): return re.findall(r'''[\d][^5678]''', stri, re.X|re.I)

print(good_numbers(string))

I need a function that returns all numbers that arent 5, 6, and 7. I got to this function from realizing I'm utterly out of ideas on what to do. I noticed that the last number in the negated set still shows up in the string... So my question is:

  1. Why is the last number in the set not negated?
  2. When doing a findall on \d alone. It returns each individual number. But as soon as a add the negated set. It returns them in double digits.... ie 12, 34,ect instead of 1, 2, 3, 4. I'm really curious as to why that is happening.
  3. And finally, what it is that I'm doing wrong??? What it is it about this function that isn't right? Why cant I get 1, 2, 3, 4, 8, 9, 0?

Trying to coomplete quiz: https://teamtreehouse.com/library/regular-expressions-in-python/introduction-to-regular-expressions/negated-numbers

negate.py
import re

string = '1234567890'

def good_numbers(stri):
    return re.findall(r'''[\d][^5678]''', stri, re.X|re.I)

1 Answer

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,457 Points

Hey Andy McDonald, you’re on the right path but the structure is not correct.

  • the challenge asks to define a variable, not define a function. Use the form good_numbers = re.findall(...
  • with r‘[\d][^5678]', you are matching two characters at a time. This regex says “match any digit that isn’t followed by a 5, 6, 7, or 8”.

By looking at pairs of numbers, the pattern “consumes” both numbers, so only five matching attempts are done in a string of ten characters:

  • “12”, passes since 2 is not in “5678”
  • “34”, passes since 4 is not in “5678”
  • “56”, fails since 6 is in “5678”
  • “78”, fails since 8 is in “5678”
  • “90”, passes since 0 is not in “5678”

What you want instead is “any single character that is not 5, 6, 7”, that is, r’[^567]’

Additionally,

  • you can use instead of ’’’, since you don’t a multiple line pattern
  • neither of the re options are required since you are not using verbose mode and do not need to ignore case

Post back if you need more help. Good luck!!!