0

The logic for testing a string agains a regex is only working when the if statement is preceded by a console.log including matching logic.

I have tried directly using the value returned from this.props, rewriting the code into an if/else if statement, reordering the statements, removing other statements, changing the logic in the console.log.

    const operatorRegex = /[+]|[-]|[*]|[/]/g,
      equalsRegex = /[=]/g,
      numberRegex = /[\d]/g,
      decimalRegex = /[.]/g,
      currentSumLength = this.props.inputSeq.length,
      currInput = e.target.textContent,
      firstChar = this.props.inputSeq[0],
      prevSum = this.props.prevSum,
      prevChar = this.props.lastInput;

    if(operatorRegex.test(currInput)) {
      if((currentSumLength === 0) && (prevSum === '')) {
        alert('Why you starting a sum with an operator?');
      }
      console.log(operatorRegex.test(prevChar))
      if(operatorRegex.test(prevChar)) {
        alert('Two in a row');
      }

      this.props.inputOperator(currInput)
    } else if (Other logic) {
      Other Code
    }

When the user inputs two operators (+,-,/,=) it should alert with the error.

MakingStuffs
  • 666
  • 1
  • 9
  • 17

1 Answers1

1

TL;DR: Remove the g modifier in the regex since you are only testing one char at a time


This is due to an interesting side-effect of the global modifier of the regular expression.

Because you use the g modifier, the regular expression (operatorRegex) will keep a state of the lastIndex it matched.

Example:

const regex = /cat/g
const str = "catcat"

console.log(regex.test(str)) // True
// It found the first "cat" and set the internal `lastIndex` to 3.

console.log(regex.test(str)) // True
// It found the second "cat" and set the internal `lastIndex` to 6.

console.log(regex.test(str)) // False
// It couldn't find a "cat" after the index 6.
// It then set `lastIndex` back to 0

console.log(regex.test(str)) // True again

So, as we can see: when running multiple time the same regex, we can have different results because of the statefulness!

However, if we do not specify the g modifier, the regex will not change the lastIndex attribute, therefore will not be stateful.

Errorname
  • 2,228
  • 13
  • 23
  • TL even more DR: don't log the result of a function - in this case you should (probably temporarily) do: `tmpVar = func(); console.log(tmpVar); if(tmpVar ...)` – MikeB Aug 13 '19 at 16:27
  • That would not fix this issue. Here it only works **because** they logs it and therefore execute it one more time which set the lastIndex to 0. If they didn't, the index wouldn't be set to 0 and it would return true – Errorname Aug 13 '19 at 16:45
  • Thank you so much! I will definitely be paying much more attention to the identifiers I use with regexes from now on. I didn't think anything bad could come from using global. Out of interest would there have been any other side effects to look out for? – MakingStuffs Aug 13 '19 at 17:48
  • I agree, that's why I didn't post it as an answer - but it _would_ have helped the poster because the strange behaviour would go away, and the value passed into the `if` would actually have been the same as what was logged. – MikeB Aug 14 '19 at 09:01