Trying to understand lookahead example

Tell us what’s happening:

let password = "abc123";
let checkPass = /(?=\w{3,6})(?=\D*\d)/;
checkPass.test(password);

Looking at the example freecodecamp provides (pasted above ): why do we need the \D* ?

Could someone please explain in detail, with an example? I read in another post to remember that the lookahead starts reading at the beginning of the phrase you’re testing, but I could not find that information anywhere else, and I’m having a hard time understanding.

Challenge: Positive and Negative Lookahead

Link to the challenge:

the \D stands for ‘not a digit’ and the * behind it indicates that its zero or more, i.e. zero or more non digit characters.
The particular lookahead (?=\D*\d) looks for string which contains at least a single digit inside it and can have multiple non-digits ahead. Im not sure i describe it correct, but it should make sense.
To better understand regex expressions you can use a site like https://regex101.com/ to assist you with testing various combinations, see how they differ on different strings to be matched
Further note on lookaheads: they are used to check if something is there, without returning it, unlike normally, when you would search for something, which you want to be returned. E.g. in regular circumstances, for example you could make a regex which looks for a name in a sentence to return that name and utilize it in later actions. In the case of lookaheads, you simply make sure there is a name, you dont care what the name is, you just need the assurance it is there(or that it is not).

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:

  1. between 3 and 6 characters, and
  2. 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.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.