Positive and Negative Lookahead : Confused about solution

I am a bit confused about the regex solution for this problem:

Use lookaheads in the pwRegex to match passwords that are greater than 5 characters long and have two consecutive digits.


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

1.) Doesn’t (?=\w{5,}) mean “search/match password that is at least 5 characters long?” The question asks for a match that is greater than 5 characters long (not greater than or equal to 5 characters) so I would have assumed the answer for the first lookahead to be /(?=\w{6,})

2.) In the second lookahead : (?=\D*\d{2}) , I don’t understand why the \D* is followed up by \d{2}. \D* means to search for non-digit characters 0 or more times and then it is followed up by “search for 2 consecutive digit characters.” Why do we need the \D* in the lookahead if all we are looking for in this lookahead is the 2 consecutive digits?

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/regular-expressions/positive-and-negative-lookahead

That question comes up frequently. There is an implied AND between those two lookaheads so you are looking for places where both lookaheads can be true.

I posted on this fairly recently so I’ll just link to that

1 Like

ah ok this makes more sense now.

I’m still confused about my 1st question though: Why use /(?=\w{5,}) and not /(?=\w{6,}) for the first lookahead if the question asks for a password that is greater than 5 characters long?

I’m not sure. I’m wondering if the challenge has been reworked recently in an attempt to clarify the required task. Clearly one test case needs to check for that condition.

You could create an issue for this on the FCC github. Seems that someone should look into that.

But is it really an AND if the first lookahead influences the second? I’ve been struggling for hours to figure out why (?=\d{2}) doesn’t work in that challenge but (?=\D*\d{2}) does. I think most of my confusion was caused by me assuming there was an AND between lookaheads. Nearly every explanation I’ve read implies they are separate queries, yet that can’t be the case if (?=\d{2}) doesn’t work. (?=\d{2}) by itself matches two consecutive digits in a string, but it stops working when you combine it as (?=\w{5,})(?=\d{2}). If these were independent queries, both would be true and the result of ANDing them would be true.

1 Like

I can appreciate your struggle. This is dense material.

For this regex/(?=\w{5,})(?=\d{2,})/ with this password astronaut22
there is a place where this is true (?=\w{5,}) and there is a place where this is true (?=\d{2,})
but there is no one place where both (?=\w{5,}) AND (?=\d{2,}) are true at the same time.
.test() is looking for a place where both will be true so in this case would return false.

For the same regex both are true for astron22aut at the point of |
astron|22aut
Since there is a place where both could be true then RegExp.test() will return true.

You can probably learn more by tinkering than from my amateurish explanations. I worked this out on repl.it. Additionally, using string.match() shows at which index the regular expression is true. Fork it if you like.

2 Likes

Thank you. I interpreted AND in the sense of a boolean operation applied to totally independent operations because of statements like this about lookaheads…

The difference is that lookaround actually matches characters, but then gives up the match, returning only the result: match or no match.

You can chain three more lookaheads after the first, and the regex engine still won’t move.

The fact that lookaround is zero-length automatically makes it atomic. As soon as the lookaround condition is satisfied, the regex engine forgets about everything inside the lookaround.

Your post is the first thing I’ve read that explains how multiple lookaheads work together with each other. I searched for things like ‘chaining’ ‘combining’ ‘multiple’ lookaheads and was not able to find an explanation about it anywhere.

try using http://www.regex101.com to test your regular expressions. it’s a really great tool that I just recently found!