Regular expression does not validate a password when I just enter numbers

3

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

I'm using this 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.

    
asked by anonymous 22.10.2018 / 03:15

1 answer

3

First let's look at your regex and understand why it does not 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]* . Brackets define a character class , which basically means "get whatever's in the brackets". Therefore, [A-Za-z0-9] means "any character that is a capital letter ( A-Z ), or lowercase letter ( a-z ) or a digit ( 0-9 )".

The quantizer * means "zero or more occurrences". Therefore the [A-Za-z0-9]* excerpt means "zero or more occurrences of letters or numbers". That is, if you have any letters (or just letters), it does. If you have any numbers (or just numbers), it will do. And if it does not have anything, it also works (since * indicates " zero or more occurrences").

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

+ indicates "one or more occurrences", so \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 for your case, it must be at least 8 characters long.

And finally, we have [A-Za-z0-9]* , which means "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 quantizers * and + do not require to be at least 8 characters (since 1 character would already be sufficient). The only thing this regex forces is that it has at least one digit ( \d+ ).

Solution

One way to solve this regex would be:

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

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

Then we have (?=.*[0-9]) . The parentheses with a question mark and equal (?=) mean that this excerpt is a lookahead >. Basically, it's a way to make the regex "look what's in front" and see if it hits the expression inside the parentheses. Within lookahead we have .*[0-9] , which means "zero or more occurrences of any character ( .* ) followed by a digit ( [0-9] )". That is, it is a regex that checks for a digit in the string.

The "trick" is that lookahead checks for a digit but then "back to where it was" (in this case, the beginning of the string) and checks the rest of the expression. That is, (?=.*[0-9]) checks for any digits and then returns to the beginning of the string and continues evaluating the rest of the regex.

Next we have another lookahead : (?=.*[a-zA-Z]) . It is similar to the previous one, but now it checks for any letters, and then returns to where it was (in this case, the beginning of the string) and continues evaluating the rest of the regex.

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

That is:

  • 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 remainder ( [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 place it after the comma. For example, {8,20} would limit the string to 8 to 20 characters.

You can see this regex working here .

    
22.10.2018 / 15:24