Медленный запрос регулярного выражения, когда строка содержит специальные символы - PullRequest
0 голосов
/ 08 января 2020

У меня есть регулярное выражение: /^(\s*\(*\s*[0-9]*\s*[+\-*/]?\s*[0-9]*\s*\)*\s*)*$/ оно не идеально, но оно разработано для быстрой проверки того, что вводимая строка является математической формулой c, например, 7 * 9 * (6 + 5). Я делаю вторичные проверки, если это проходит, чтобы найти незамкнутые скобки (формула также может заканчиваться оператором).

Javascript String.prototype.match может использовать регулярное выражение для очень быстрого сопоставления с некоторыми строками, например, "7 * 912 + 6 + 7 +".match(regex), но очень медленно с другими:

  1. "7 * 912 + 6 + $ +".match(regex)
  2. "7 * 912 + 6 + ^ +".match(regex)
  3. "7 * 912 + 6 + [ +".match(regex)
  4. "7 * 912 + 6 + ] +".match(regex)

Однако это быстро для: "7 * 912 + $ +".match(regex)

Предположительно, причина этого в том, что строка содержит специальные символы в сочетании с? в середине (проблема исчезнет, ​​если я уберу это) - но только когда объединено определенное количество операторов? Есть ли способ улучшить производительность этого? Прямо сейчас я просто проверяю любые специальные символы (так как ни один не разрешен), но я бы хотел что-нибудь почище.

1 Ответ

1 голос
/ 08 января 2020

Обнаружение правильно сформированного выражения довольно сложно - я бы не пытался все это использовать одним регулярным выражением - я бы расширил ваш подход с несколькими проходами до уровня, необходимого для удовлетворения ваших потребностей. Я бы определенно начал с базового c символьного фильтра:

var charRegex = /[^0-9+\-*\(\)\s]/i;
function testString(str) {
    if (!charRegex.test(str)) {
        // fail
        return false;
    }
    // do further tests...
}

Ваше дальнейшее тестирование может включать в себя регулярные выражения для проверки нескольких операторов подряд, незакрытые скобки и т. Д. c. И если вы сделаете это внутри функции, вы сможете вернуться к первому неудачному тесту на раннем этапе.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...