Hawkeye Hawkeye - 3 months ago 18
Javascript Question

Regex not matching numbers

I am trying to parse through math within strings. It works for x*y but not

x*y*z
. I think it has to do with one is a string while the other is a number. But I can't find a way to get around it.

Here is my code:

var reMD = /(\d+) *[\*|\/] *(\d+)/g
var str = '17 * 13 * 4';
var ex;
runWhile();

function runWhile() {
var ex = reMD.exec(str);
if (ex !== null) {
if (ex.index === reMD.lastIndex) {
reMD.lastIndex++;
}
if (ex[0].indexOf('*') !== -1) {
var rep = parseInt(ex[1]) * parseInt(ex[2])
} else {
var rep = parseInt(ex[1]) / parseInt(ex[2])
}
var rep = rep.toString()
str = str.replace(ex[0], rep)
if (reMD.exec(str) !== null) {
runWhile()
}
}
}
alert(str)


The alert sends back
221 * 4
but it should come back as
884
. How would I fix this?

Answer

It should work if you remove the g flag from your regex, because then each time you call .exec() it will start afresh as explained at MDN. You can also remove the code that is messing with reMD.lastIndex.

(With the g flag, it tries to match from the index of where the previous match ended, but you are trying to match against a new string.)

Note also that you could change your regex to match the operator too, rather than using indexOf(), and you don't really need to call parseInt() because the * and / operators will coerce their operands to numbers:

var reMD = /(\d+) *([\*|\/]) *(\d+)/
var str = '17 * 13 / 4';  // note I've change the input to demostrate * and /
runWhile();

function runWhile() {
   var ex = reMD.exec(str);
   if (ex !== null) {
     if (ex[2]==="*") {
       var rep = ex[1] * ex[3]
     } else {
       var rep = ex[1] / ex[3]
     }
     rep = rep.toString()
     str = str.replace(ex[0], rep)
     if (reMD.exec(str) !== null) {
       runWhile()
     }
   }
}
console.log(str)

(Note: it's still a little bit untidy for the function to be using and modifying variables defined outside the function, but I'll leave any further tidy-up as an exercise for the reader...)

Comments