0

Please note that this is not a question about regex themselves, it's about some weird behaviors I am detecting. I'm experiencing several tricky behaviors with javascript regular expressions. If I evaluate each code step individually, it works as expected so I think I may be incurring in some kind of state problem within regular expressions.

The first problem It's that I can not directly access the index of a regex exec result. For example

const regex = /a(bc)/gm;
regex.test('abc') && regex.exec('abc')[1] // => can not acces 1 of null

I tried saving the result to a variable and then try to conditionally access the value, but then I am always getting false

const doRegex = str => { 
  const regexRes = randomRegex.exec(str); 
  return randomRegex.test(str) ? regexRes[1] : str 
}

console.log(doRegex('abc')) // => prints abc  instead of bc

It was very hard to figure out a good title for the issue, so any suggestion to update is welcome.

Danielo515
  • 5,996
  • 4
  • 32
  • 66

1 Answers1

0

The problem resides on the global g flag of the regular expression.

Adding that flag makes the regular expression become global and that makes the regular expression to retain state. For that reason, the first time you execute the regular expression ( does not matter if it is by executing .test or by executing .exec), you are initializing the regular expression state. The first time you execute the regular expression you are going to get true on the .test case or a correct match on the .exec case. By the next time you execute again the regular expression, it will "advance" it's state, trying to match the next result. Since your string only matches once you will get null as result and the regular expression will reset it's state.

Your options are, removing the global flag or declaring the regular expression inside the function body (to avoid state retention) and execute it just once.

const doRegex = str => { 
  const regexRes = (/a(bc)/gm).exec(str); 
  return regexRes ? regexRes[1] : str 
}

That code only executes the regular expression once and everytime the function is executed a new regular expression object gets created so you will not have the state retention problem that will happen if you declare the regular expression outside the function.

EDIT: @LGSon commented that you can also pass the parameters you want to the different regex functions:

If you pass the flags as parameters to the regex functions it will work. E.g. randomRegex.exec(str, /gm/); ... randomRegex.test(str,/gm/)

Danielo515
  • 5,996
  • 4
  • 32
  • 66