Spec-Zone.ru › JavaScript

RegExp.prototype.exec()

Базовая поддержка Широко доступно

Эта функция хорошо зарекомендовала себя и работает на многих устройствах и версиях браузеров. Она доступна во всех браузерах с июля 2015 года.

Метод exec() экземпляров RegExp выполняет поиск совпадения для данного регулярного выражения в указанной строке и возвращает результирующий массив, или null.

Попробуйте

const regex = /fo+/g;
const str = "table football, foosball";
let array;

while ((array = regex.exec(str)) !== null) {
  console.log(`Found ${array[0]}. Next starts at ${regex.lastIndex}.`);
  // Expected output: "Found foo. Next starts at 9."
  // Expected output: "Found foo. Next starts at 19."
}

Синтаксис

exec(str)

Параметры

str
Строка, в которой ищется совпадение с регулярным выражением. Все значения приводятся к строкам, поэтому, если вы опустите его или передадите undefined, exec() будет искать строку "undefined", что редко является желаемым поведением.

Возвращаемое значение

Если совпадение не найдено, метод exec() возвращает null и устанавливает свойство lastIndex регулярного выражения в 0.

Если совпадение найдено, метод exec() возвращает массив и обновляет свойство lastIndex объекта регулярного выражения. Возвращаемый массив содержит найденный текст как первый элемент, а затем по одному элементу для каждой захватывающей группы найденного текста. Массив также имеет следующие дополнительные свойства:

index
Индекс совпадения в строке (начиная с 0).
input
Исходная строка, в которой производился поиск совпадения.
groups
Объект без прототипа (null) именованных захватывающих групп, где ключами являются имена, а значениями — захватывающие группы, или undefined, если именованные захватывающие группы не были определены. См. захватывающие группы для получения дополнительной информации.
indices Необязательно

Это свойство присутствует только тогда, когда установлен флаг d. Это массив, в котором каждая запись представляет границы совпадения подстроки. Индекс каждого элемента в этом массиве соответствует индексу соответствующего совпадения подстроки в массиве, возвращаемом exec(). Другими словами, первая запись indices представляет полное совпадение, вторая запись indices представляет первую захватывающую группу и т.д. Каждая запись сама по себе является массивом из двух элементов, где первое число представляет начальный индекс совпадения, а второе число — его конечный индекс.

Массив indices дополнительно имеет свойство groups, которое содержит объект без прототипа (null) всех именованных захватывающих групп. Ключами являются имена захватывающих групп, и каждое значение представляет собой массив из двух элементов, где первое число — это начальный индекс, а второе число — конечный индекс захватывающей группы. Если регулярное выражение не содержит именованных захватывающих групп, groups равно undefined.

Описание

Объекты JavaScript RegExp являются сохраняющими состояние (stateful), когда у них установлены флаги global или sticky (например, /foo/g или /foo/y). Они хранят значение lastIndex, полученное после предыдущего совпадения. Используя это свойство, exec() может использоваться для итерации по нескольким совпадениям в текстовой строке (с захватывающими группами), в отличие от получения только совпадающих строк с помощью String.prototype.match().

При использовании exec() глобальный флаг не имеет эффекта, если установлен флаг sticky — совпадение всегда является липким (sticky).

exec() — это примитивный метод регулярных выражений. Многие другие методы регулярных выражений вызывают exec() внутри, включая те, которые вызываются строковыми методами, такими как [Symbol.replace](). Хотя сам exec() является мощным (и наиболее эффективным), он часто не передает намерение наиболее ясно.

  • Если вам важно только, соответствует ли регулярное выражение строке, а не то, что именно было найдено, используйте RegExp.prototype.test().
  • Если вы ищете все вхождения глобального регулярного выражения и вас не интересует информация о захватывающих группах, используйте String.prototype.match(). Кроме того, String.prototype.matchAll() помогает упростить сопоставление нескольких частей строки (с захватывающими группами), позволяя вам выполнять итерацию по совпадениям.
  • Если вы выполняете сопоставление, чтобы найти его позицию (индекс) в строке, используйте метод String.prototype.search().

exec() полезен для сложных операций, которые не могут быть легко реализованы с помощью любого из вышеперечисленных методов, часто когда вам необходимо вручную настроить lastIndex. (String.prototype.matchAll() копирует регулярное выражение, поэтому изменение lastIndex во время итерации по matchAll не влияет на итерацию.) Один из таких примеров см. в разделе сброс lastIndex.

Примеры

Использование exec()

Рассмотрим следующий пример:

// Match "quick brown" followed by "jumps", ignoring characters in between
// Remember "brown" and "jumps"
// Ignore case
const re = /quick\s(?<color>brown).+?(jumps)/dgi;
const result = re.exec("The Quick Brown Fox Jumps Over The Lazy Dog");

В следующей таблице показано состояние result после выполнения этого скрипта:

Свойство Значение
[0] "Quick Brown Fox Jumps"
[1] "Brown"
[2] "Jumps"
index 4
indices [[4, 25], [10, 15], [20, 25]]
groups: { color: [10, 15 ]}
input "The Quick Brown Fox Jumps Over The Lazy Dog"
groups { color: "Brown" }

Кроме того, re.lastIndex будет установлено в 25, поскольку это регулярное выражение является глобальным.

Поиск последовательных совпадений

Если ваше регулярное выражение использует флаг g, вы можете использовать метод exec() несколько раз для поиска последовательных совпадений в одной и той же строке. В этом случае поиск начинается с подстроки str, указанной свойством lastIndex регулярного выражения (test() также продвигает свойство lastIndex). Обратите внимание, что свойство lastIndex не будет сброшено при поиске в другой строке; поиск начнется с существующего значения lastIndex.

Например, предположим, что у вас есть следующий скрипт:

const myRe = /ab*/g;
const str = "abbcdefabh";
let myArray;
while ((myArray = myRe.exec(str)) !== null) {
  let msg = `Found ${myArray[0]}. `;
  msg += `Next match starts at ${myRe.lastIndex}`;
  console.log(msg);
}

Этот скрипт отображает следующий текст:

Found abb. Next match starts at 3
Found ab. Next match starts at 9

Предупреждение: Есть много подводных камней, которые могут привести к тому, что это станет бесконечным циклом!

  • Не помещайте литерал регулярного выражения (или конструктор RegExp) внутрь условия while — это приведет к повторному созданию регулярного выражения при каждой итерации и сбросу lastIndex.
  • Убедитесь, что установлен глобальный флаг (g), иначе lastIndex никогда не будет продвигаться.
  • Если регулярное выражение может соответствовать символам нулевой длины (например, /^/gm), увеличивайте его lastIndex вручную при каждой итерации, чтобы избежать застревания на одном и том же месте.

Обычно вы можете заменить этот тип кода на String.prototype.matchAll(), чтобы сделать его менее подверженным ошибкам.

Использование exec() с литералами RegExp

Вы также можете использовать exec() без явного создания объекта RegExp:

const matches = /(hello \S+)/.exec("This is a hello world!");
console.log(matches[1]);

Это выведет сообщение, содержащее 'hello world!'.

Спецификации

Спецификация
ECMAScript® 2027 Language Specification
# sec-regexp.prototype.exec

Совместимость с браузерами

Десктопные Мобильные Серверные
Chrome Edge Firefox Opera Safari Chrome Android Firefox for Android Opera Android Safari on iOS Samsung Internet WebView Android WebView on iOS Bun Deno Node.js
exec
1
12
1
5
1
18
4
10.1
1
1.0
4.4
1
1.0.0
1.0
0.10.0

Смотрите также

  • Руководство по регулярным выражениям
  • RegExp

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API