Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RegEx for at least 1 number, 1 lower case and 1 upper case letter

Tags:

html

regex

Currently, I'm using one that I found with a length restriction:

<input #password="ngModel" type="password" name="password"  minlength="5" maxlength="30" pattern="((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,20})" required ngModel>

It works, but I don't want the length restriction at the end. I don't know much about regular expressions, so I assumed that removing {6,20} at the end would get the job done, but I was wrong.

So my question is: How do I make this regex work without the length restriction? Thanks!

like image 712
Jesper Avatar asked Mar 30 '17 20:03

Jesper


People also ask

How do you match upper and lower cases in regex?

Using character sets For example, the regular expression "[ A-Za-z] " specifies to match any single uppercase or lowercase letter. In the character set, a hyphen indicates a range of characters, for example [A-Z] will match any one capital letter.

What does ?= Mean in regex?

?= is a positive lookahead, a type of zero-width assertion. What it's saying is that the captured match must be followed by whatever is within the parentheses but that part isn't captured. Your example means the match needs to be followed by zero or more characters and then a digit (but again that part isn't captured).

What is case letter Islower?

Lowercase letters are the shorter, smaller versions of letters (like w), as opposed to the bigger, taller versions (like W), which are called uppercase letters or capital letters. The adjective lowercase can also be used as a noun meaning the same thing as lowercase letter, though this is much less commonly used.

What does * do in regex?

This operator is similar to the match-zero-or-more operator except that it repeats the preceding regular expression at least once; see section The Match-zero-or-more Operator ( * ), for what it operates on, how some syntax bits affect it, and how Regex backtracks to match it.


1 Answers

You are using an HTML5 pattern attribute that anchors a regex by default (it actually wraps the pattern with ^(?: and )$). That means the pattern must match the entire string. This is the reason why you can't just take out .{6,20} and keep the lookaheads.

You need to use the lookaheads at the beginning, and .* (to allow 0 or more chars in the input) or .+ (to disallow empty input) at the end (as the consuming pattern part):

pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*"

This will be successfully translated into /^(?:(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*)$/ and will work as expected:

  • ^ - start of string
  • (?: - start of the non-capturing group
    • (?=.*\d) - 1 digit after any 0+ chars from the current position is required
    • (?=.*[a-z]) - 1 lowercase letter after any 0+ chars from the current position is required
    • (?=.*[A-Z]) - 1 uppercase letter after any 0+ chars from the current position is required
  • .* - any 0 or more chars
  • ) - end of the non-capturing group
  • $ - end of string.
like image 162
Wiktor Stribiżew Avatar answered Oct 12 '22 04:10

Wiktor Stribiżew