Regular expression does not validate password when I type only numbers

Asked

Viewed 618 times

4

I am using this regular expression to validate my password, the password must have only letters and numbers, must have at least a letter and a number. (Minimum 8 characters).

I’m using that expression:

[RegularExpression(@"^[A-Za-z0-9]*\d+[A-Za-z0-9]*$")]

When I type qwertyu1 it validates correctly.

The error is when I type 12345678 it validates without typing a letter.

  • 3

    Yes, that’s what your Regex asks. It doesn’t require any lyrics. You put as optional (*) the two groups with letter inside, and mandatory (+) only digits.

1 answer

6


First let’s look at your regex and understand why it doesn’t work:

^[A-Za-z0-9]*\d+[A-Za-z0-9]*$

The markers ^ and $ indicate, respectively, the beginning and end of the string.

Then we have [A-Za-z0-9]*. The brackets define a character class, which basically means "take anything that’s in the brackets". So [A-Za-z0-9] means "any character that is a capital letter (A-Z), or lower case letter (a-z) or one digit (0-9)".

Already the quantifier * means "zero or more occurrences". Therefore [A-Za-z0-9]* means "zero or more occurrences of letters or numbers". That is, if you have any letters (or only letters), it is good. If you have any numbers (or only numbers), it is also good. And if you have nothing, it is also good (since the * indicates "zero or more occurrences").

Then we have \d+. The \d is a shortcut to [0-9] - but depending on the language/engine/configuration used, the \d can also match other digits (such as characters ٠١٢٣٤٥٦٧٨٩), as explained in this answer. If you want to ensure that your regex will accept only the ASCII digits (from 0 to 9), use [0-9].

Already the + indicates "one or more occurrences", therefore \d+ means "one or more occurrences of digits". Note that it can be any quantity greater than or equal to 1, so this is not good for your case, which needs to be at least 8 characters long.

And finally, we have again [A-Za-z0-9]*, meaning "zero or more occurrences of letters or numbers".

That is, this regex does not require you to have at least one letter, as it defines that zero or more occurrences of letters or numbers are accepted. In addition, the quantifiers * and + do not require at least 8 characters (since 1 character would be sufficient). The only thing this regex requires is that it has at least one digit (\d+).


Solution

One way to settle would be this regex:

^(?=.*[0-9])(?=.*[a-zA-Z])[a-zA-Z0-9]{8,}$

The markers ^ and $ indicate, respectively, the beginning and the end of the string. With this, we ensure that the entire string contains only what is in regex.

Next we have (?=.*[0-9]). Parentheses with question mark and equal (?=) means that this passage is a Lookahead. Basically, it is a way to do the regex "look at what’s in front" and see if it matches the expression inside the parentheses. Inside the Lookahead we have .*[0-9], meaning "zero or more occurrences of any character (.*) followed by a digit ([0-9])". That is, it is a regex that checks if it has a digit in the string.

The "trick" is that the Lookahead checks if there is a digit but then "goes back to where it was" (in this case, the beginning of the string) and checks the rest of the expression. Ie, (?=.*[0-9]) checks if there are any digits and then goes back to the beginning of the string and continues to evaluate the rest of the regex.

Next we have another Lookahead: (?=.*[a-zA-Z]). It is similar to the previous one, only now checks for some letter, and then goes back to the position where it was (in this case, the beginning of the string) and continues to evaluate the rest of the regex.

Next we have [a-zA-Z0-9]{8,}. The [a-zA-Z0-9] means "letters or numbers", and the quantifier {8,} means "8 or more occurrences".

That is to say:

  • the first Lookahead ((?=.*[0-9])) ensures that there is at least one digit in the string
  • the second Lookahead ((?=.*[a-zA-Z])) ensures that there is at least one letter in the string
  • the rest ([a-zA-Z0-9]{8,}) ensures that there are at least 8 characters in the string (and that all characters are letters or numbers)

If you also want to limit the maximum size, you can put it after the comma. For example, {8,20} would limit the string to 8 to 20 characters.

You can see this regex working here.

  • 1

    Thank you for the solution and for explaining how regular expression works.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.