Ответ 1
Хорошо, я вижу это сейчас. Ключом к вашей проблеме является использование флага g
(global match): когда это указано для регулярного выражения, оно будет настроено так, что оно может выполняться несколько раз, начиная каждый раз в том месте, где оно осталось в последний раз. Он хранит "закладки" в своем свойстве lastIndex
:
var testRegex = /blah/ig;
// logs: true 4
console.log(testRegex.test("blah blah"), testRegex.lastIndex);
// logs: true 9
console.log(testRegex.test("blah blah"), testRegex.lastIndex);
// logs: false 0
console.log(testRegex.test("blah blah"), testRegex.lastIndex);
В приведенном выше примере создается экземпляр очень простого регулярного выражения: он соответствует "блаху", верхнему или нижнему регистру, где угодно в строке, и его можно сопоставить несколько раз (флаг g
). В первом прогоне он соответствует первому "блаху" и оставляет lastIndex
равным 4 (индекс пробела после первого "блаха" ). Второй запуск начинается с соответствия lastIndex
, соответствует второму блаху и оставляет lastIndex
установленным на 9 - один за концом массива. Третий пробег не соответствует - lastIndex
является фиктивным - и оставляет lastIndex
равным 0. Таким образом, четвертый пробег будет иметь те же результаты, что и первый.
Теперь ваше выражение довольно немного жаднее моего: оно будет соответствовать любому количеству символов до или после "бла". Поэтому, независимо от того, какую строку вы тестируете, если она содержит "blah", она всегда будет соответствовать всей строке и оставьте lastIndex
установленной длиной только что протестированной строки. Если вы хотите дважды позвонить test()
, второй тест всегда будет терпеть неудачу:
var filterRegex = /.*blah.*/ig;
// logs: true, 9
console.log(filterRegex.test("blah blah"), filterRegex.lastIndex);
// logs: false, 0
console.log(filterRegex.test("blah blah"), filterRegex.lastIndex);
К счастью, поскольку вы создаете свое регулярное выражение непосредственно перед вызовом test()
и никогда не вызываете test()
более одного раза, вы никогда не столкнетесь с неожиданным поведением... Если используя отладчик, который позволяет добавить в другой вызов к test()
сбоку. Ага. При запуске Firebug выражение watch, содержащее ваш вызов test()
, приведет к появлению прерывистых результатов false
, либо в вашем коде, либо в результатах просмотра, в зависимости от того, какой из них будет первым. Вождение вас медленно безумие...
Конечно, без флага g, livin 'легко:
var filterRegex = /.*blah.*/i;
// logs: true, 0
console.log(filterRegex.test("blah blah"), filterRegex.lastIndex);
// logs: true, 0
console.log(filterRegex.test("blah blah"), filterRegex.lastIndex);
Предложения
- Избегайте глобального флага, когда он вам не нужен.
- Будьте осторожны с тем, что вы оцениваете в отладчике: если есть побочные эффекты, это может повлиять на поведение вашей программы.