-1

I am trying to make a regular expression that can check the strength of password. A password is considered to be strong if:

  • It has minimum length of 8 characters
  • It must contains minimum 2 Upper case and 2 Lower case letter
  • It must contains minimum 2 digits
  • It must contains minimum 2 special characters from $,%,&,!,#

This is what i have done:

# Strong Password Checker
import re

password_regex = re.compile(r'[(A-Z){2}(a-z){2}(0-9){2}($%&!#){2}]{8,}')
if password_regex.match('testpassword'):
    print("Your password is strong")
else:
    print("Your password is weak")

The password supplies to this code is not strong but, it doesn't detect it as weak password, Instead it identifies it as strong password.

Initially i am learning regular expression, so i want to keep everything simple and clear, if someone help it would be really appreciated.

Sheri
  • 1,383
  • 3
  • 10
  • 26
  • 1
    `[(A-Z){2}(a-z){2}(0-9){2}($%&!#){2}]` is a character class that accepts any single symbol there. So, it accepts, `(`, and then `A-Z`, and `)`, and `{`, and `2`, and `}`, and so on. – VLAZ Apr 28 '20 at 15:21
  • Not every string problem is a regular expression problem, and this is a good example where some simple code (e.g. `len(password)`, judicious use of `isupper()` and `islower()` or `string.ascii_uppercase`, etc.) would be _much_ simpler and clearer. – ChrisGPT was on strike Apr 28 '20 at 15:48
  • @Sheri, partly because it has already been asked. Please remember to search before asking a new question. – ChrisGPT was on strike Apr 28 '20 at 15:49
  • @Chris yes you are saying right that it could be better to use `isupper()` or `islower()` but as i mention in my that i am learning regex so i have to made it using regex, BTW thanks for you response and motivation – Sheri Apr 28 '20 at 15:55

1 Answers1

1

You may use multiple lookahead conditions in your regex:

^(?=(?:[^A-Z]*[A-Z]){2})(?=(?:[^a-z]*[a-z]){2})(?=(?:\D*\d){2})(?=(?:[^$%&!#]*[$%&!#]){2}).{8,}$

Or making it easier to read using x mode:

^
(?=(?:[^A-Z]*[A-Z]){2})
(?=(?:[^a-z]*[a-z]){2})
(?=(?:\D*\d){2})
(?=(?:[^$%&!#]*[$%&!#]){2})
.{8,}
$

RegEx Demo

RegEx Details:

  • ^: Start
  • (?=(?:[^A-Z]*[A-Z]){2}): Lookahead condition to make sure there are minimum 2 uppercase letters
  • (?=(?:[^a-z]*[a-z]){2}): Lookahead condition to make sure there are minimum 2 lowercase letters
  • (?=(?:\D*\d){2}): Lookahead condition to make sure there are minimum 2 digits
  • (?=(?:[^$%&!#]*[$%&!#]){2}): Lookahead condition to make sure there are minimum 2 of the given special characters
  • .{8,}: Make sure we have 8 or more of length
  • $: End
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • Note that it might be easier to read if you do it in several steps, all commented : one regex to check digits, one to check max characters, etc, and fail if any regex fail – LogicalKip Apr 28 '20 at 15:26
  • 1
    Once we breakup this longish regex into different components like this: https://regex101.com/r/nu01Ed/2 then it is easier to understand. – anubhava Apr 28 '20 at 15:28