См. Документацию MDC по test
.
Если вы хотите узнать, найден ли образец в строке, используйте метод test (аналог String.searchметод);для получения дополнительной информации (но более медленного выполнения) используйте метод exec (аналогичный методу String.match).Как и в случае с exec, test, вызванный несколько раз для одного и того же экземпляра регулярного выражения, будет проходить после предыдущего совпадения .
. Решение состоит в том, чтобы удалить глобальный или g
флаг из вашегорегулярные выражения:
/[a-z]/
вместо /[a-z]/g
и т. д.
Рассмотрим простой пример , чтобы понять причину проблемы:
var l = /[a-z]/g;
// initial search starts at the beginning, matches "a" and returns true
l.test("a"); // true
// since the first character matched, lastIndex moves to the next index - 1
l.lastIndex; // 1
// this time we pass a different string to the regex, but unfortunatly it
// starts searching from the lastIndex which is 1. There are no lower case
// letters from this point onwards (only "---"), so return value is false.
l.test("x---"); // false
// Since this search failed, lastIndex wraps around to the beginning, so the
// next search will work as expected
l.lastIndex; // 0
Для заданного вами значения "aaasdfF#3s"
тест [a-z]
в нижнем регистре будет успешным 7 раз, так как есть 7 символов нижнего регистра, но не пройден 8-й раз.И снова добиваться успеха с 9 по 15 раз и так далее.Другие тесты будут проходить каждый раз поочередно, так как есть только один символ каждого типа - "F"
, "#"
и "3"
, и он оборачивается от lastIndex
до 0, когда тест не пройден.
Проблема, по-видимому, связана с тем, что состояние сохраняется в этих объектах RegExp между вызовами функций, то есть объект RegExp создается только один раз, а не каждый раз, когда вызывается функция.Этот небольшой тест подтверждает это:
function RegExpStatePersistenceTest() {
var regex = /[a-z]/g;
regex.counter = regex.counter || 0;
regex.counter++;
console.log("counter:" + regex.counter);
}
RegExpStatePersistenceTest(); // counter: 1
RegExpStatePersistenceTest(); // counter: 2
RegExpStatePersistenceTest(); // counter: 3
RegExpStatePersistenceTest(); // counter: 4
Если новый объект был явно создан с использованием new RegExp(..)
, то при каждом вызове функции будет создаваться новый новый объект RegExp,и состояние не будет сохраняться между вызовами.
Также см. why-regexp-with-global-flag-in-javascript-give-неправильный-результаты