First, to clarify, in the description
> password checker that looks for between 3 and 6 characters and at least one number
characters refer to any word character, specifically [a-zA-Z0-9_]. I frequently misread it to mean alphabets. But it actually includes digits, too. To paraphrase, we’re looking for
a pattern between 3 and 6 characters, of which at least one of them is a digit.
The lookahead pattern is very useful if we are looking for multiple conditions. Here we have two conditions, that the pattern has:
- between 3 and 6 characters, and
- at least one of them is a digit.
The regex (?=\w{3,6})
checks the first condition and (?=\D*\d)
the second. Here are some examples:
a12 //okay, matches both conditions
113 //okay, matches both conditions
a2 //not okay, matches (?=\D*\d)
but not (?=\w{3,6})
1abc //okay, matches both.
2c. //not okay, matches (?=\D*\d)
but not (?=\w{3,6})
So, why is the lookahead pattern useful? Because without it, you have to express many different exact patterns, such as
a digit followed by 2 or more characters
a character followed by a digit and then by one or more characters
and so forth. Lookahead will let you check for multiple conditions independently.
Suppose you don’t use a lookahead and write
/\w{3,6}\D*\d
then you’re saying you’re looking for a pattern that has 3 to 6 characters followed by zero or more non-digits and then a digit. Pattern like abc
won’t get matched.
Lastly, your question about why \D*
is necessary. If you don’t, i.e., use (?=\d)
instead, then you’re looking for a pattern that starts with a digit. So, a pattern like 1ab
matches (Both conditions are matched) but a1b won’t (matches (?=\w{3,6})
but not (?=\d)
).
Regex is really tricky because it is so easy to under-match or over-match. Use the website regex101, as mentioned, to quickly experiment with patterns.