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 trialigsm '
10,440 PointsBoolean with re?
Hey. Can you help please with the following. Using RE, I want to check a string, which is meant to be a passwords. True if it contains >= 10 chars, at least one lower letter, one capital letter and one number; else False. How would a code look like. Thanks.
e.g. two cases:
True = 'bAse730onE4'
False = 'saaaa90'
re.match('[a-zA-Z0-9]+', password)
3 Answers
Chris Freeman
Treehouse Moderator 68,457 PointsBecause you are looking for the AND
of multiple conditions there isn't a short single concise regexp that will solve your needs because your conditions are not order dependent. That is, you would have to check for all combinations of a condition followed by all others. For example lowercase followed by uppercase followed by number and being 10 characters long, plus the other 5 combinations, OR
ed together in a single regexp.
The other option is to create the 3 search patterns and check that they each match plush a length check.
patterns = []
patterns.append(re.compile(r'[a-z]+')) #lowercase
patterns.append(re.compile(r'[A-Z]+')) #uppercase
patterns.append(re.compile(r'[0-9]+') )# number
password_good = True
if len(password_string) < 10:
password_good = False
else:
for pat in patterns:
if not pat.search(password_string):
# pattern not found
password_good = False
break
You could include the length check as a regexp:
patterns.append(re.compile(r'\w{10,}'))
I'll work on the combined uber-regexp to show it's complications and ammend my answer.
EDIT: Here is a single regexp pattern to match against. Yeah, it's not pretty:
In [101]: patx = re.compile(r'''
\w*[a-z]+\w*[A-Z]+\w*[0-9]+\w*|
\w*[a-z]+\w*[0-9]+\w*[A-Z]+\w*|
\w*[A-Z]+\w*[a-z]+\w*[0-9]+\w*|
\w*[A-Z]+\w*[0-9]+\w*[a-z]+\w*|
\w*[0-9]+\w*[a-z]+\w*[A-Z]+\w*|
\w*[0-9]+\w*[A-Z]+\w*[a-z]+\w*
''', re.X)
In [102]: patx.search("")
In [103]: patx.search("a")
In [104]: patx.search("aA1")
Out[104]: <_sre.SRE_Match object; span=(0, 3), match='aA1'>
Now you can use:
if not len(password) > 10 and patx.search(password)
print("Bad Password")
Tatiana Jamison
6,188 PointsHi Igor, re.search and re.match return match objects. If the item isn't found, it returns None (the special value). re.match checks for a match at the beginning of the string, whereas re.search checks anywhere in the string. You can use the boolean operator "and" to check multiple conditions--for example:
def check_two(string):
return re.search(\w+) and re.search(\d+)
returns True if the string contains at least one word character ([a-zA-Z0-9_]) and at least one decimal digit. You can get more specific by using a set definition, like [a-z]+.
igsm '
10,440 PointsThank you. Really helpful!
Chris Freeman
Treehouse Moderator 68,457 PointsChris Freeman
Treehouse Moderator 68,457 PointsAdded uber-regexp to answer.
If switching to
re.match
instead of search, use thepatx
as above:re.match(patx, password)
If you choose to switch to
re.search
, you can remove the leading and trailing\w*
from each line in thepatx
regexp.Tatiana Jamison
6,188 PointsTatiana Jamison
6,188 PointsThis works, too:
Technically, it actually returns None when the password is bad, but that's fine in a lot of applications. Easy modification if the False return is important: