Подтвердить что ты не робот

Regex в javascript терпит неудачу каждый раз с одинаковым вводом

Простой тест script:

<script type="text/javascript">
    var reg = new RegExp('#([a-f0-9]{3})$', 'gi');
    for (var i = 0; i < 10; i++) {
        console.log(reg.exec('#fff'));
    }
</script>

Выход консоли:

["#fff", "fff"]
null
["#fff", "fff"]
null
["#fff", "fff"]
null
["#fff", "fff"]
null
["#fff", "fff"]
null

Почему каждый другой результат равен нулю, когда вход остается постоянным?

4b9b3361

Ответ 1

Когда вы используете глобальный флаг, регулярное выражение становится "липким". То есть он использует переменную счетчика для отслеживания, где было найдено последнее совпадение. Вместо того, чтобы начинать каждый раз с первого раза, липкое регулярное выражение фактически забирает место, где заканчивается последний матч. Этот счетчик будет только reset вернуться к 0 (начало), если полное совпадение не удастся (поэтому он работает каждый раз)

В вашем случае моим предложением было бы сбросить флаг g.

Для получения дополнительной информации: RegExp @MDC

Ответ 2

Matt ответил, почему. Я просто хотел добавить, что вы можете увидеть это, проверив значение lastIndex объекта RegExp до и после вызова exec

var reg = new RegExp('#([a-f0-9]{3})$', 'gi');
for (var i = 0; i < 10; i++) {
    console.log(reg.lastIndex);
    console.log(reg.exec('#fff'));
    console.log(reg.lastIndex);
}

вывод

0
["#fff", "fff"]
4

4
null
0

0
["#fff", "fff"]
4

4
null
0

0
["#fff", "fff"]
4

4
null
0

0
["#fff", "fff"]
4

4
null
0

0
["#fff", "fff"]
4

4
null
0

undefined

демонстрируя, что на каждой другой итерации цикла совпадение регулярных выражений начинается с завершения lastIndex. Вы можете установить lastIndex в 0 перед каждым вызовом exec или вообще удалить флаг.

Ответ 3

Ваша проблема заключается в "gi" во втором аргументе, я просто удалил его и протестировал на консоли Chrome:

var reg = new RegExp('#([a-f0-9]{3})$');

Ответ 4

Я нашел это в Интернете...

Вызов функции exec() также изменяет свойство lastIndex объекта RegExp.
Он сохраняет индекс в строке темы, в которой начнется следующая попытка совпадения.
Вы можете изменить это значение, чтобы изменить начальную позицию следующий вызов exec().

Поведение, которое вы описываете, указывает, что объект RegExp имеет состояние, которое изменяется, вызывая метод exec().

Я думаю, вам нужно изменить свойство lastIndex до повторного запуска метода exec.
подробнее здесь: Javascript Regexp Object