0

I was checking a simple Regexp to check if a word has a letter or not, thus I ended using something like:

new RegExp(/[A-Z]/gi)

this regexp will be executed/tested each time that the user changes an input, lets suppose it is typing really fast, so I created this litte snippet:

const hasLettersExpression = new RegExp(/[A-Z]/gi);
const hasLetters = str => hasLettersExpression.test(str);

for (let i = 0; i < 10; i++) {
  // we always test against the same string.
  console.log(i, '--->', hasLetters('12ab'))
}

which from my perspective is giving the following result:

0 ---> true
1 ---> true
2 ---> false
3 ---> true
4 ---> true
5 ---> false
6 ---> true
7 ---> true
8 ---> false
9 ---> true

which is not correct, because it should always return true.

does anyone know why is this happening? there is a patter of true, true, false ... is this related?

Prince Hernandez
  • 3,623
  • 1
  • 10
  • 19
  • 1
    RegExp objects track how much of the string they have searched and continue from there next time you use them. If you want to search from the beginning of the string again without creating a new RegExp object, set `hasLettersExpression.lastIndex = 0;` before reusing it. – Paul Jul 11 '19 at 16:15
  • This answer might help: https://stackoverflow.com/a/1520853/8237835 – Khauri Jul 11 '19 at 16:17

1 Answers1

2

A regexp created with the global 'g' flag will remember the last match index when invoking test.

If the regex has the global flag set, test() will advance the lastIndex of the regex. A subsequent use of test() will start the search at the substring of str specified by lastIndex (exec() will also advance the lastIndex property). It is worth noting that the lastIndex will not reset when testing a different string. (mdn)

const regex = new RegExp(/[A-Z]/gi);
const str = '12ab';

for (let i = 0; i < 10; i++)
  console.log(i, '--->', regex.test(str), regex.lastIndex);
junvar
  • 11,151
  • 2
  • 30
  • 46