Regex иногда возвращает ноль в Javascript

1

При использовании регулярного выражения для соответствия значениям внутри строки формулы я нашел эту проблему, что regex вернет null, даже если есть совпадение.

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);

В приведенном выше фрагменте вы можете увидеть результат, что несколько значений не заменяются, но в то же время все они обнаруживаются с помощью regex101 https://regex101.com/r/WTpvFq/1. По какой-то причине я не могу сузить то, что я делаю неправильно, даже прочитав несколько разных ответов на подобные проблемы.

Я мог бы использовать обходной путь и использовать formula.match(qtyRegex) но я действительно уверен, что это просто ошибка в Regex, поэтому я бы предпочел правильно ее исправить, вместо того, чтобы намазать его патчем.

  • 0
    Использование .replace внутри цикла .exec выглядит неуместно. Что ты на самом деле делаешь? Кроме того, [a-zA-Z_-|\d] - ошибка, вероятно, вы хотели использовать [\w-]
Теги:

2 ответа

1
Лучший ответ

Вместо цикла в то время как вы можете напрямую заменить с помощью RegExp с replacer обратного вызова string.replace, как это:

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
}
  • 0
    @ WiktorStribi - новый заменитель может быть функцией, и вот где должны быть манипуляции, я уточню ответ для уточнения.
  • 0
    Просто для ясности. Каждый QTY [число] представляет собой строку, представляющую различное количество в списке элементов. Поэтому я не хочу заменять все совпадения одним и тем же значением. Вот почему я решил заменить строку в цикле
Показать ещё 5 комментариев
0

Когда вы используете модификатор g в regexp, он запоминает позицию в строке, в которой он был последним, и последующие совпадения начинаются с этой позиции. Но ваш код заменяет совпадение более короткой строкой, поэтому запомненная позиция может пройти мимо начала следующего матча, и она не находит ее.

Избавьтесь от g модификатора, и он будет искать с самого начала каждый раз.

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);

Ещё вопросы

Сообщество Overcoder
Наверх
Меню