Regular Expressions: Positive and Negative Lookahead

I know I’m not the first to ask about this exercise, but I only have a very specific question.

So for this exercise:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/regular-expressions/positive-and-negative-lookahead

The requirement is “match passwords that are greater than 5 characters long and have two consecutive digits.”

Whereas the solution is:

/(?=\w{5,})(?=\D*\d{2})/

My question is: Why the \D?

The first lookahead runs through and makes sure there are at least 5 characters, so with that passed, I’d expect the next step to just be ensuring there are two consecutive numbers. Why is it required there be an additional check for non-numbers in the second lookahead?

What the regex is looking for is either five word characters (which does include digits), OR any number of non-digits followed by two digits. Without the \D, it would fail to match “xy12”.

Regexes consisting of only lookaheads are very unusual in real-world applications.

Since I can’t seem to edit my last post … I was quite wrong there. BOTH of the lookahead assertions have to match, so what it’s matching is a string of at least five word characters, but one that must contain at least two digits. Without the \D*, it would fail to match on “foo12” since it would have to match the digits at the same place as the first assertion matched, and “foo” doesn’t contain digits.

Again, regexes containing only lookaheads are rare and therefore kind of confusing.

1 Like

This is a commonly asked question, perhaps the solution’s explanation should be better

The reason is that the match must have two consecutive digits, but we don’t care exactly where they are in the password

So in the second lookahead, there can be any number of non-digits followed by a pair of digits

Lookaheads look ahead of the current position when evaluating matches

2 Likes

That makes sense – thank you both! Indeed, it is tricky to wrap the mind around, but I think I git the gist of it at least.