1

While using regex to match values inside of a formula string I found this issue that regex would return null even though there is a match.

var formula = "round((DATAtotal_sq_ft * .6) + (QTY16 * 4) + (QTY17 * 2) + QTY18 + QTY15 + QTY12 * 18 / 3000, 1)";

const qtyRegex = /(QTY)(\d*)|(LEN)(\d*)|(DATA)([a-zA-Z_-|\d]*)/gm;
let m;

while ((m = qtyRegex.exec(formula)) !== null) {
  var val = 0; // Here is irrelevant code that gets the value
  formula = formula.replace(m[0], val);
}
console.log(formula);

In the above snippet you can see the result that a couple of the values don't get replaced but at the same time all of them get detected by regex101 https://regex101.com/r/WTpvFq/1. For some reason I cant seem to narrow down what I'm doing wrong even after reading a number of different answers to similar problems.

I could use a workaround and use formula.match(qtyRegex) but I am really certain it's just an error in the Regex so I'd prefer properly fixing it instead of plastering it with a patch.

1
  • Using .replace inside an .exec loop does not look appropriate. What are you really doing? Besides, [a-zA-Z_-|\d] is an error, probably you wanted to use [\w-] Commented Jun 12, 2018 at 18:52

2 Answers 2

1

Instead of a while loop you can directly replace using the RegExp with the replacer callback of String.replace like this:

formula = formula.replace(qtyRegex, replacer)

// take a look at the docs I've linked above for an explanation of these params
function replacer(match, p1, p2, ..., offset, string) {
  let calculatedValue = 0 // perform your irrelevant code that gets the value here
  return calculatedValue
}
Sign up to request clarification or add additional context in comments.

7 Comments

@WiktorStribiżew the replacer can be a function, and that's where the manipulation should be, I'll update the answer for clarification.
Just to clarify. Each QTY[number] is a string representing a different quantity in a list of items. So I don't want to replace all of the matches with the same value. That's why I opted to replace with string in a loop
@wp78de The replacer callback alternative was created with this exact intent
@TrevorReimer Using a while is a bit dirty in my eyes, as the alternative's pretty simple, but who am I to judge I guess.
@GMaiolo I see your point now. I got it working but i'll definitely try and improve it with your tips
|
1

When you use the g modifier in a regexp, it remembers the position in the string where it last matched, and subsequent matches start from that position. But your code is replacing the match with a shorter string, so the remembered position may be past the beginning of the next match, and it doesn't find it.

Get rid of the g modifier and it will search from the beginning each time.

var formula = "round((DATAtotal_sq_ft * .6) + (QTY16 * 4) + (QTY17 * 2) + QTY18 + QTY15 + QTY12 * 18 / 3000, 1)";

const qtyRegex = /(QTY)(\d*)|(LEN)(\d*)|(DATA)([a-zA-Z_-|\d]*)/m;
let m;

while ((m = qtyRegex.exec(formula)) !== null) {
  var val = 0; // Here is irrelevant code that gets the value
  formula = formula.replace(m[0], val);
}
console.log(formula);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.