How do lookaheads work with other code?

Hello, I was having some trouble understanding lookaheads when used with other code.

Breaking it down, from my understanding, the first lookahead is stating that there must be 6 alphanumerics (including _).

The first part of the second lookahead says that its looking for 0 or more alphanumerics. But why do this if the first lookahead already finds 6.

The second part of the second lookahead says its looking for two or more consecutive numerical numbers. And since this is the second lookahead, does it have to be at the end or no because it doesnt have the $ at the end.

And what’s the point of having two separate lookaheads instead of all in one (I know that the code wont work).

I personally dont like this method of checking passwords, I prefer the way they made us do it in a previous challenge
Your code so far


let sampleWord = "astronaut";
let pwRegex =  /(?=\w{6})(?=\w*\d{2})/;
let result = pwRegex.test(sampleWord);

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36 Edg/94.0.992.50

Challenge: Positive and Negative Lookahead

Link to the challenge:

A more practical use of lookaheads is to check two or more patterns in one string. Here is a (naively) simple password checker that looks for between 3 and 6 characters and at least one number:

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

Above is the example from the lesson, emphasis mine. To rephrase it in code, you could have done it with two separate regular expressions and no lookaheads:

let password = "abc123";
let chechAlpha = /\w{3,6}/;
let checkTrailingNum = /\D*\d/;
checkAlpha.test(password) && checkTrailingNum.test(password);

But with the lookaheads, you can do it all in one regular expression. That’s all.

This is indeed a little confusing and I’ll try my best to explain it.

/(?=\w{6})/ by itself will match a string with six alphanumeric characters in a row

and

/(?=\d{2})/ by itself will match a string with 2 consecutive numbers regardless of where those 2 consecutive numbers occur

So why do you need to add \w* to the beginning of the latter when you combine these in order for them to work together properly?

With multiple lookaheads like this, in order for the regex to find a match, both of the lookaheads must be true at the same time. The key here is that the latter will search the string until it finds two consecutive numbers, and it is at this point (where the first of the two numbers is found) that the first lookahead must also be true (i.e. \w{6} is applied to the string starting at the first number).

Let’s take a look at an example without the \w* in the second lookahead.

/(?=\w{6})(?=\d{2})/

The string “11abcd” will be a match because at the point where the two consecutive numbers begin there are also six alphanumeric characters in a row. So both of the lookaheads are satisfied at the same time.

The string “ab11cd” will not match however because at the point where the two consecutive numbers begin there are only four consecutive alphanumeric characters left in the string and thus the first lookahead is not fulfilled. Side note: If we add two more alphanumeric characters to the end of the string (e.g. “ab11cdef”) then it will match again because there are now six alphanumeric characters beginning at the first “1”.

Now let’s add the \w* to the second lookahead and use it on the string “ab11cd”:

/(?=\w{6})(?=\w*\d{2})/

The second lookahead will find “11” as in the examples above. But the \w* means “find 0 or more alphanumeric characters before these two numbers” and thus the second lookahead can gobble up the two alphanumeric characters that precede “11” so they are now included in the second lookahead. In essence, the second lookahead moves its starting point back to the “a” and since there are six alphanumeric characters beginning at “a” the first lookahead is also satisfied.

Basically, each lookahead has the potential to move the starting point at which the other lookahead(s) must also start from.