2

I want a regex which returns true when there is at least 5 characters et 2 digits. For that, I use a the lookahead (i. e. (?=...)).

// this one works
let pwRegex = /(?=.{5,})(?=\D*\d{2})/;
let result = pwRegex.test("bana12");

console.log("result", result) // true

// this one won't
pwRegex = /(?=.{5,})(?=\d{2})/;
result = pwRegex.test("bana12");

console.log("result", result) // false

Why we need to add \D* to make it work ?

For me, \d{2} is looser than \D*\d{2} so it should not allow an acceptance of the test?

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
pom421
  • 1,731
  • 19
  • 38
  • It's for a challenge in freeCodeCamp ;). – pom421 Aug 16 '18 at 12:00
  • But I have to admit that it seems a convenient solution to make these 2 guesses : i want 5 characters AND i want 2 digits in it. How to do without lookahead? – pom421 Aug 16 '18 at 12:05

2 Answers2

2

Your lookaheads only test from the current match position. Since you don't match anything, this means from the start. Since bana12 doesn't start with two digits, \d{2} fails. Its as simple as that ;)

Also, note that having \d{2} means your digits has to be adjacent. Is that your intention?

To simply require 2 digits, that doesn't need to be adjacent, try

/(?=.{5,})(?=\D*\d\D*\d)/
Paolo
  • 21,270
  • 6
  • 38
  • 69
SamWhan
  • 8,296
  • 1
  • 18
  • 45
1

Note that lookaheads are zero-width assertions and when their patterns are matched the regex index stays at the same place where it has been before. The lookaheads in the patterns above are executed at the same locations.

The /(?=.{5,})(?=\d{2})/ pattern will match a location that has any 5 chars other than line break chars immediately to the right of the current location and the first 2 chars in this 5 char substring are digits.

You need to add \D* to let other types of chars before the 2 digits.

See more about that behavior at Lookarounds Stand their Ground.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563