Объекты RegExp определяют два метода, выполняющие поиск по шаблону; они ведут себя аналогично методам класса String, описанным ранее. Основной метод класса RegExp, используемый для поиска по шаблону, – это exec(). Он похож на упоминавшийся метод match() класса String, за исключением того, что является методом класса RegExp, принимающим в качестве аргумента строку, а не методом класса String, принимающим аргумент RegExp. Метод exec() исполняет регуляр_ ное выражение для указанной строки, т. е. ищет в строке соответствие. Если со_ ответствие не найдено, метод возвращает null. Однако если соответствие найде_ но, он возвращает такой же массив, как массив, возвращаемый методом match() для поиска без флага g. Нулевой элемент массива содержит строку, соответст_ вующую регулярному выражению, а все последующие элементы – подстроки, соответствующие всем подвыражениям. Кроме того, свойство index содержит но_
11.3. Объект RegExp
мер позиции символа, которым начинается соответствующий фрагмент, а свой_ ство input ссылается на строку, в которой выполнялся поиск.
В отличие от match(), метод exec() возвращает массив, структура которого не за_ висит от наличия в регулярном выражении флага g. Вспомните, что при переда_ че глобального регулярного выражения метод match() возвращает массив най_ денных соответствий. А exec() всегда возвращает одно соответствие, но предос_ тавляет о нем полную информацию. Когда exec() вызывается для регулярного выражения, содержащего флаг g, метод устанавливает свойство lastIndex объек_ та регулярного выражения равным номеру позиции символа, следующего непо_ средственно за найденной подстрокой. Когда метод exec() вызывается для того же регулярного выражения второй раз, он начинает поиск с символа, позиция которого указана в свойстве lastIndex. Если exec() не находит соответствия, свойство lastIndex равно 0. (Вы также можете установить lastIndex в ноль в лю_ бой момент, что следует делать во всех тех случаях, когда вы завершаете поиск до того, как нашли последнее соответствие в одной строке и начинаете поиск в другой строке с тем же объектом RegExp.) Это особое поведение позволяет нам вызывать exec() повторно для перебора всех соответствий регулярному выраже_ нию в строке. Например:
var pattern = /Java/g;
var text = "JavaScript – это более забавная штука, чем Java!"; var result;
"; следующий поиск начинается с " + pattern.lastIndex);
}
Еще один метод объекта RegExp – test(), который намного проще метода exec(). Он принимает строку и возвращает true, если строка соответствует регулярному выражению:
var pattern = /java/i; pattern.test("JavaScript"); // Возвращает true
Вызов test() эквивалентен вызову exec(), возвращающему true, если exec() воз_ вращает не null. По этой причине метод test() ведет себя так же, как метод ex_ ec() при вызове для глобального регулярного выражения: он начинает искать указанную строку с позиции, заданной свойством lastIndex, и если находит соот_ ветствие, устанавливает свойство lastIndex равным номеру позиции символа, не_ посредственно следующего за найденным соответствием. Поэтому мы можем сформировать с помощью метода test() цикл обхода строки так же, как с помо_ щью метода exec().
Методы search(), replace() и match() класса String не задействуют свойство last_ Index, в отличие от методов exec() и test(). На самом деле методы класса String просто сбрасывают lastIndex в 0. Если мы используем exec() или test() с шабло_ ном, в котором установлен флаг g, и выполняем поиск в нескольких строках, то мы должны либо найти все соответствия в каждой строке, чтобы свойство last_ Index автоматически сбросилось в ноль (это происходит, когда последний поиск оказывается неудачным), либо явно установить свойство lastIndex, равным ну_ лю. Если этого не сделать, то поиск в новой строке может начаться с некоторой
228 Глава 11. Шаблоны и регулярные выражения
произвольной позиции, а не с начала. И наконец, помните, что особое поведение свойства lastIndex относится только к регулярным выражениям с флагом g. Ме_ тоды exec() и test() игнорируют свойство lastIndex объектов RegExp, в которых отсутствует флаг g.