1

I tried to validate my password using RegExp. I wrote following code,

    var pass = jQuery('#new_password').val(); 
    // Minimum six characters, at least one uppercase letter, one lowercase letter and one number
    var reg = new RegExp("^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{6,}$");
    if (reg.test(pass)) {
        alert(1);
    } else {
        alert(2);
    }

However, even If I entered complex password according to my requirement (Minimum six characters, at least one uppercase letter, one lowercase letter and one number), Condition's true part (if condition) does not execute.

Could someone please help me to solve this? thank you.

Gayan
  • 2,845
  • 7
  • 33
  • 60
  • 1
    According to your regex, it will be matching 6 or more characters, **which are preceded by the conditional characters**. That is to say, even 6 character passwords won't be enough. – Robo Mop Jan 17 '19 at 04:05
  • @CoffeehouseCoder thanks for the comment, but it does not work for even 10 character password. – Gayan Jan 17 '19 at 04:07
  • You might find [Reference - Password Validation](https://stackoverflow.com/q/48345922/3600709) useful. – ctwheels Mar 27 '19 at 15:25

5 Answers5

3

Change your regex to:

^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)[A-Za-z\d@$!%*#?&]{6,}$

not forgetting a g flag.

  • When using: (?=.*[A-Za-z]) it will pass if user types only uppercase or lowercase letters.

  • When using: (?=.*[@$!%*#?&]) you are requiring user to type some special character.

    var pass = 'TestString123'; 
    // Minimum six characters, at least one uppercase letter, one lowercase letter and one number
    var reg = new RegExp(/^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)[A-Za-z\d@$!%*#?&]{6,}$/g);
    if (reg.test(pass)) {
        alert(1);
    } else {
        alert(2);
    }
guijob
  • 4,413
  • 3
  • 20
  • 39
1

Try something like this instead? Separate each test out so it's a bit more manageable. IMO.

export function validatePassword(password, repeatPassword) {
  // password tests
  const hasUpperCase = /[A-Z]/.test(password)
  const hasLowerCase = /[a-z]/.test(password)
  const hasNumbers = /\d/.test(password)
  const hasSpecial = /\W/.test(password)
  let errors = []

  if (password !== repeatPassword) {
    errors.push('Passwords do not match.')
  }
  if (password.length < 6) {
    errors.push('Password must be at least 6 characters long.')
  }
  if (!hasUpperCase) {
    errors.push('Password must contain at least one uppercase letter.')
  }
  if (!hasLowerCase) {
    errors.push('Password must have at least one lowercase letter.')
  }
  if (!hasNumbers) {
    errors.push('Password must have at least one number.')
  }
  if (!hasSpecial) {
    errors.push('Password must have at least one special character.')
  }

  return errors
}

export default validatePassword;

I find it easier to separate each test instead of one regex. You can also provide the user with the specific failure.

rimraf
  • 3,925
  • 3
  • 25
  • 55
1

You can try this out:

^(?=.*?[a-z])(?=.*?[A-Z])(?=.*?\d)[A-Za-z\d@$!%*#?&]{6,}$

As shown here: https://regex101.com/r/GAkedL/1

Explanation -

Here, we match each condition separately, because in your code the first lookahead implies "followed by either a lowercase or uppercase letter".

(?=.*?[a-z]) tells the regex that the password should have 0 or more characters followed by a lowercase letter
(?=.*?[A-Z]) tells the regex that the password should have 0 or more characters followed by an uppercase letter
(?=.*?\d) tells the regex that the password should have 0 or more characters followed by a digit

Note the addition of ? after .* in each lookahead. This implies that the regex should match as few characters as possible before finding the letter or digit required, which is more efficient.

Community
  • 1
  • 1
Robo Mop
  • 3,485
  • 1
  • 10
  • 23
0

You need to make some modifications to your regular expression.

To match a minimum of 6 characters with at least 1 letter and 1 number, you could use the following expression:

"^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$"

But to ensure that at least 1 of the letters is also uppercase, you'll need to add an additional condition. The below expression should match for a minimum of 6 characters, with at least 1 uppercase letter, 1 lowercase letter, and 1 number:

"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$"
JoshG
  • 6,472
  • 2
  • 38
  • 61
0

Try this!

   export function validatePassword(password) {
      // password testing
      const hasUpperCase = /[A-Z]/.test(password)
      const hasLowerCase = /[a-z]/.test(password)
      const hasNumbers = /\d/.test(password)
      const hasSpecial = /\W/.test(password)
      let errors = []
    
      if (password.length < 6) {
        errors.push('Password must be at least 6 characters long.')
      }
      if (!hasUpperCase) {
        errors.push('Password must contain at least one uppercase letter.')
      }
      if (!hasLowerCase) {
        errors.push('Password must have at least one lowercase letter.')
      }
      if (!hasNumbers) {
        errors.push('Password must have at least one number.')
      }
      if (!hasSpecial) {
        errors.push('Password must have at least one special character.')
      }
    
      return errors
    }
    
    export default validatePassword;