Этот метод ищет совпадение с regexp в строке str. В отличие от предыдущих методов, вызывается на регулярном выражении, а не на строке.
Он ведёт себя по-разному в зависимости от того, имеет ли регулярное выражение флаг g:
- если нет g, то regexp.exec(str) возвращает первое совпадение в точности как str.match(regexp).
- если есть g, то вызов regexp.exec(str) возвращает первое совпадение и запоминает позицию после него в свойстве regexp.lastIndex. Следующий такой вызов начинает поиск с позиции regexp.lastIndex, возвращает следующее совпадение и запоминает позицию после него в regexp.lastIndex. Если совпадений больше нет, то regexp.exec возвращает null, а для regexp.lastIndex устанавливается значение 0.
Таким образом, повторные вызовы возвращают одно за другим все совпадения, используя свойство regexp.lastIndex для отслеживания текущей позиции поиска.
В прошлом, до появления метода str.matchAll в JavaScript, вызов regexp.exec в цикле использовали для получения всех совпадений с их позициями и группами скобок в цикле.
Это работает и сейчас, хотя для современных браузеров str.matchAll, как правило, удобнее.
Мы можем использовать regexp.exec для поиска совпадения, начиная с нужной позиции, если вручную поставим lastIndex. Например:
let str = 'Hello, world!';
let regexp = /\w+/g; // без флага g свойство lastIndex игнорируется
regexp.lastIndex = 5; // ищем с 5-й позиции (т.е с запятой и далее)
alert( regexp.exec(str) ); // world
Если у регулярного выражения стоит флаг y, то поиск будет вестись не начиная с позиции regexp.lastIndex, а только на этой позиции (не далее в тексте). Это удобно в тех ситуациях, когда мы хотим «прочитать» что-то из строки по регулярному выражению именно на конкретной позиции, а не где-то далее.
В примере выше заменим флаг g на y. Ничего найдено не будет, поскольку именно на позиции 5 слова нет:
let str = 'Hello, world!';
let regexp = /\w+/y;
regexp.lastIndex = 5; // ищем ровно на 5-й позиции
alert( regexp.exec(str) ); // null