Как закалялся код...: Javascript - регулярные выражения (Regexp) - использование флага глобального поиска - g

вторник, 22 декабря 2015 г.

Javascript - регулярные выражения (Regexp) - использование флага глобального поиска - g

Просто показался интересным результат следующего javascript кода:


var javascriptLiteralRegex = /[HhMmSs]/g;
console.log(javascriptLiteralRegex.test('M')); // true
console.log(javascriptLiteralRegex.test('M')); // false
console.log(javascriptLiteralRegex.test('M')); // true
console.log(javascriptLiteralRegex.test('M')); // false

Имеем один экземпляр регулярного выражения в переменной javascriptLiteralRegex.
Метод 'test' проверяет есть ли совпадения регулярного выражения со строкой.

Причина такого результата выполнения в том, что флаг глобального поиска 'g' говорит интерпретатору что при каждом последующем запуске поиск будет выполнен с того индекса на котором было найдено последнее совпадение в строке поиска и сбрасывает его только если результат поиска был ошибочен.

Т.е. в данном случае после каждого успешного (нечетного) вызова в свойстве lastIndex регулярного выражения будет сохранено значение найденного индекса плюс один (1) (т.к. один символ в строке поиска):

var javascriptLiteralRegex = /[MmHhSs]/g;
console.log(javascriptLiteralRegex.lastIndex); // 0
console.log(javascriptLiteralRegex.test('M')); // true
console.log(javascriptLiteralRegex.lastIndex); // 1
console.log(javascriptLiteralRegex.test('M')); // false
console.log(javascriptLiteralRegex.lastIndex); // 0
console.log(javascriptLiteralRegex.test('M')); // true
console.log(javascriptLiteralRegex.lastIndex); // 1
console.log(javascriptLiteralRegex.test('M')); // false

Если бы пример был реальным то флаг глобального поиска вообще бы не понадобился, и это решает проблему:

var javascriptLiteralRegex = /[MmHhSs]/;
console.log(javascriptLiteralRegex.test('M')); // true
console.log(javascriptLiteralRegex.test('M')); // true

Кстати индекс вполне доступен для изменения:

var javascriptLiteralRegex = /[HhMmSs]/g;
console.log(javascriptLiteralRegex.test('M')); // true
javascriptLiteralRegex.lastIndex = 0;
console.log(javascriptLiteralRegex.test('M')); // true

А что если бы на каждый вызов был создан новый объект регулярного выражения:

console.log(/[HhMmSs]/g.test('H')); // true
console.log(/[HhMmSs]/g.test('H')); // true

Комментариев нет:

Отправить комментарий