Regular Expressions - Positive and Negative Lookahead

Tell us what’s happening:
I do not understand why why solution does not work, but the given solution does.

Your code so far

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

The above fails, as does /(?=\w{6,})(?=\d\d)/. However, when I add \w*, as in the given solution, it will pass. I do not understand why the \w* is necessary.

Should \d\d and \d{2} not correctly search for 2 consecutive numbers?

Your browser information:

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

Challenge: Regular Expressions - Positive and Negative Lookahead

Link to the challenge:

Too long to explain again. Recycling answer from another post.

I see

So when 1 of the search parameters is met, it restricts the search to the point where it was met? Then if all parameters cannot be met within that restriction, it fails. All of them have to be true at the same time, rather than at varying points.

Thank you very much.

In regular expressions, both \d\d and \d{2} are used to search for two consecutive digits (numbers) in a string, so they are functionally equivalent. However, the issue you’re experiencing isn’t related to the \d\d or \d{2} part of the regular expression but rather the (?=\w{6,}) part, which specifies a positive lookahead for at least 6 word characters.

Here’s an explanation of why the given solution with \w* works:

  1. In the original regular expression, (?=\w{6,}) asserts that there must be at least 6 word characters ahead in the string. This means that the string must contain 6 or more consecutive word characters for the regex to match.
  2. In the given solution with \w*, * is a quantifier that matches zero or more of the preceding \w character. So, \w* will match any number (including zero) of word characters.
  3. By using \w*, the regular expression becomes less restrictive. It allows for strings with fewer than 6 consecutive word characters to match, as long as there are still two consecutive digits present (\d\d or \d{2}).

So, if you want to make your original regex work just like I did in my emirates id official module, you can modify it like this:

javascriptCopy code

let sampleWord = "astronaut";
let pwRegex = /(?=\w*\d\d)/; // Change this line
let result = pwRegex.test(sampleWord);

This change should make the regular expression pass for strings like “astronau23t” because it now allows for zero or more word characters (\w*) before the two consecutive digits (\d\d).

In regular expressions, quantifiers like {n} or * specify the number of times a pattern should be matched:

  • {n} specifies exactly n occurrences.
  • * specifies zero or more occurrences.
  • + specifies one or more occurrences.
  • ? specifies zero or one occurrence.

Now, regarding the original regex pattern (?=\w{6,})(?=\d{2}), let’s break it down:

  1. (?=\w{6,}) asserts that there must be at least 6 word characters (\w) ahead in the string. This means it will only match if there are 6 or more consecutive word characters.
  2. (?=\d{2}) asserts that there must be exactly 2 consecutive digits (\d) ahead in the string.

The issue with this regex is that it’s too restrictive because it requires both conditions to be met simultaneously:

  • At least 6 word characters.
  • Exactly 2 consecutive digits.

This means that it won’t match strings like “astronau23t” because although it has two consecutive digits, it doesn’t have at least 6 word characters in a row.

By changing the regex to (?=\w*\d\d), you are modifying the first assertion:

  • \w* now allows for zero or more word characters, making it more permissive. This means it can match strings with fewer than 6 consecutive word characters.

So, if you want to ensure that there are at least 2 consecutive digits in a string but don’t want to be too restrictive about the number of word characters before them, using \w* is a more flexible approach.

got working through this-
let pwRegex = /(?=[\w]{5,})(?=[^\d]\D*\d\d)/; or
let pwRegex = /(?=[\w]{5,})(?=[^\d]\D*\d{2})/;
is this the right way ?

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