Объект RegExp в JavaScript

Объект RegExp в JavaScript

Теперь, когда вы знаете, как формируются регулярные выражения JavaScript, настало время разобраться, как их использовать. Мы выясним это в ходе обсуждения свойств и методов объектов RegExp и String, которые могут использоваться для проверки и анализа строк. Напомним, что регулярные выражения, созданные в предыдущей статье с помощью синтаксиса литералов, на самом деле являются объектами RegExp. В этом разделе мы отдадим предпочтение объектному синтаксису, чтобы вы смогли освоить оба варианта.

test()

Простейшим методом RegExp является test() — этот метод уже использовался во многих примерах выше. Возвращаемое методом логическое ц значение указывает, соответствует ли данная строка-аргумент регулярному выражению. Ниже определяется регулярное выражение, используемое затем для проверки двух строк:

Подвыражения

Объект RegExp предлагает простой способ извлечения фрагментов строк, соответствующих части шаблона. Это достигается с помощью группирования тех частей шаблона (путем размещения вокруг них скобок), которые требуется извлечь. Предположим, нужно извлечь имена (но не фамилии) и телефонные номера из строк типа

где N обозначают цифры телефонного номера. Здесь можно использовать следующее регулярное выражение, в котором группируется часть, соответствующая имени, и часть, соответствующая телефонному номеру:

Этот шаблон можно прочитать так: один или больше символов, которые встречаются в словах, с последующим пробелом, затем еще один или больше символов, которые встречаются в словах, с последующим пробелом и, наконец, строка из восьми цифр и дефисов.

При сравнении строки с этим шаблоном скобки индуцируют подвыражения. Если сравнение оказывается успешным (т.е. обнаруживается совпадение), на эти указанные в скобках подвыражения можно ссылаться с помощью статических свойств $1 — $9 объекта класса RegExp. В продолжение нашего примера рассмотрим

Поскольку шаблон содержит скобки, с помощью которых создаются два подвыражения (\w+ и [\d-] {8}), можно отдельно сослаться на соответствующие им две подстроки — «Alan» и «555-1212». Подстроки, доступные с помощью такого подхода, нумеруются слева направо, начиная с $ 1 и заканчивая обычно $ 9. Например, в результате выполнения фрагмента программного кода

мы увидим :
RegExp.$1 = Alan
RegExp.$2 = 555-1212

Обратите внимание на то, что для доступа к компонентам-подвыражениям используется объект класса RegExp, а не созданный нами экземпляр RegExp или шаблон.

compile()

Метод compile() используется не слишком часто. Он заменяет существующее регулярное выражение новым. Этот метод предполагает те же аргументы, что и конструктор RegExp() (строка шаблона, и необязательные строки, содержащие флаги), и может использоваться для замены старого выражения новым:var pattern = new RegExp(«http:.* «,»i»);

Другой задачей использования этой функции является повышение эффективности. Регулярные выражения, объявляемые с помощью конструктора RegExp, компилируются (превращаются в подпрограммы проверки строк интерпретатором) при каждом их использовании, и это может занимать достаточно много времени, особенно в тех случаях, когда шаблон достаточно сложен. Явный вызов compile() избавляет от необходимости повторной компиляции, выполняя эту компиляцию заранее и только один раз.

ехес()

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

Метод exec() принимает в качестве аргумента строку для проверки и может вызываться в кратком виде с помощью непосредственного вызова имени регулярного выражения как функции. Например, два вызова в следующем примере эквивалентны:

Метод exec() возвращает массив с множеством свойств. Среди них length (указывает длину массива), input (содержит оригинальную входную строку), index (содержит позицию символа, с которой в строке начинается соответствие) и lastlndex (указывает позицию, где соответствие заканчивается, т.е. где будет начинаться следующий поиск). Следующий сценарий иллюстрирует использование метода exec() и возвращаемых им значений:

Результат выполнения этого фрагмента программного кода будет таким:
result = кот
result.length = 1
result.index = 8
result.lastlndex = 11
result.input = Это был кот, жирный кот по кличке Руфус.

Возвращаемый массив может содержать более одного элемента, если используются подвыражения. Например, в следующем сценарии используются три заключенные в скобки подвыражения, которые анализируются в массиве отдельно:

Результат выполнения этого фрагмента программного кода будет таким:
result = кот и пес ,кот,и,пес
result.length = 4
result.index = 4
result.lastlndex = 14
result.input = Мои кот и пес оба черные.

метод exec() размещает всю соответствующую строку в нулевом элементе массива, а подстроки, соответствующие заключенным в скобки подвыражениям, — в последующих элементах.

ехес() и флаг глобальности

Иногда требуется найти не только первое соответствие шаблону в строке, а все соответствия. Добавление флага глобальности (g) к регулярному выражению указывает на необходимость искать все совпадения, а не только первое (т.е. искать глобально).

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

Чтобы продемонстрировать разницу между регулярными выражениями с флагом глобальности и без него, рассмотрим следующий простой пример:

Как видно результата при наличии флага глобальности exec() начинает поиск с позиции, следующей за найденным соответствием. Без флага глобальности exec() всегда возвращает первую найденную часть строки.

Результат выполнения этого фрагмента программного кода будет таким:
Без флага глобальности получаем:
3
3
3
С флагом глобальности получаем:
3
14
27

Как выполняется глобальный поиск? Напомним, что exec() устанавливает свойство lastlndex как в возвращаемом массиве, так и в объекте класса RegExp, в результате чего указатель соответствует символу, следующему непосредственно за подстрокой, которая только что была найдена. При последующих вызовах метода exec() поиск в строке будет начинаться с позиции, указанной свойством lastlndex. Если соответствия не найдено, значение lastlndex устанавливается равным нулю.

При типичном использовании exec() выполняется цикл по всем подстрокам, соответствующим регулярному выражению, с получением полной информации о каждом совпадении. Примером такого использования является следующий фрагмент программного кода, в котором находятся слова в заданной строке. Результат (при условии заключения указанного программного кода в рамки дескриптора <рге>) показан ниже. Обратите внимание на то, как в соответствии с вышеприведенным обсуждением меняются значения lastlndex.

Результат выполнения этого фрагмента программного кода будет таким:
Найдено Ну
token.input = Ну очень интересное предложение.
token.index = 0
token.lastlndex = 2

Найдено очень
token.input = Ну очень интересное предложение.
token.index = 3
token.index = 8

Найдено интересное
token.input = Ну очень интересное предложение.
token.index = 9
token.lastlndex = 19

Найдено предложение
token.input = Ну очень интересное предложение.
token.index = 20
token.lastlndex = 31

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

Свойства RegExp

Использование внутренних свойств экземпляра объектов регулярных выражений и статических свойств (свойств класса) объекта RegExp может оказаться полезным как при решении сложных задач соответствия, так и при отладке. Свойства экземпляра объектов RegExp приводятся в табл.; почти все они уже известны читателю.

Свойство Значение Пример
global Логическое значение, указывающее, установлен ли флаг глобальности (g). Доступно только для чтения var pattern = /(кот)-(пес)/g;
pattern.test(«это кот-пес и кот-пес»);
document.writeln (pattern.global);
// печатает true
ignoreCase Логическое значение, указывающее, установлен ли флаг независимости от регистра (i). Доступно только для чтения var pattern = / (кот) — (пес)/g;
pattern.test(«это кот-пес и кот-пес»);
document.writeln(pattern.ignoreCase);
// печатает false
lastlndex Целое значение, указывающее позицию в строке, с которой будет начинаться следующий поиск. Это значение можно менять var pattern = /(кот)-(пес)/g;
pattern.test («это кот-пес и кот-пес»);
document.writeln(pattern.lastlndex);
// печатает 11
multiline Логическое значение, указывающее, установлен ли флаг многострочности (m). Доступно только для чтения var pattern = /(кот)-(пес)/g; pattern.test(«это кот-пес и кот-пес»);
document.writeln(pattern.multiline);
// печатает false
source Строковая форма регулярного выражения. Доступно только для чтения var pattern = /(кот)-(пес)/g;
pattern.test(«это кот-пес и кот-пес»);
document.writeln(pattern.source);
// печатает (кот)-(пес)

Объект класса RegExp имеет статические свойства, которые также могут оказаться весьма полезными. Эти свойства приведены в табл. Они могут иметь две формы. Для альтернативной формы используется знак доллара и специальный символ — эта форма знакома тем, кто уже активно работал с регулярными выражениями. Недостатком альтернативной формы является то, что доступ к ней осуществляется в режиме ассоциативного массива. Заметим, что использование этой формы, вероятно, смутит тех, кто не работал с языками типа Perl, поэтому, пожалуй, лучше ее не использовать.

Свойство Альтернативная форма Значение Пример
$1,$2…..$9 Нет Строки, соответствующие первым девяти подвыражениям в скобках для последнего найденного соответствия шаблону var pattern = /(кот)-(пес)/g;
pattern.test(«это кот-пес и кот-пес»);
document.writeln(«$l=»+RegExp.$1);
document.writeln («$2=»+RegExp.$2) ;
// печатает $1= кот $2 = пес
index Нет Значение индекса первого символа в строке, с которого начинается соответствие шаблону, найденное в результате последней операции сравнения. Это свойство имеет широкую поддержку, но не является частью стандарта ЕСМА, поэтому данное значение лучше вычислить с помощью свойства length найденной подстроки и lastlndex var pattern =/(кот)-(пес)/g;
pattern.test(«это кот-пес и кот-пес»);
document.writeln(RegExp.index);
// печатает 4
input $_ Строка, используемая для сравнения с данным шаблоном по умолчанию var pattern = / (кот)-(пес)/g;
pattern.test(«это кот-пес и кот-пес»);
document.writeln (RegExp.input);
// печатает «это кот-пес и кот-пес»
document.writeln(RegExp[‘$_’]);
// печатает «это кот-пес и кот-пес»
lastlndex Нет Целочисленное значение, указывающее позицию в строке, с которой будет начинаться следующий поиск. Соответствует значению аналогичного свойства экземпляра, которое использовать предпочтительнее var pattern = / (кот)-(пес)/g;
pattern.test(«это кот-пес и кот-пес»);
document.writeln(RegExp.lastlndex);
// печатает 11
lastMatch $& Строка с соответствующим шаблону текстом, найденным в результате последней операции сравнения var pattern = /(кот)-(пес)/g;
pattern.test(«это кот-пес и кот-пес»);
document.writeln(RegExp.lastMatch);
// печатает «кот-пес»
document.writeln(RegExp[‘$&’]);
// печатает «кот-пес»
lastParen $+ Строка, соответствующая последнему заключенному в скобки подвыражению для последнего найденного соответствия шаблону var pattern = /(кот)-(пес)/g;
pattern.test(«это кот-пес и кот-пес»);
document.writeln(RegExp.lastParen);
// печатает «пес»
document.writeln(RegExp[‘$+’]);
// печатает «пес»
leftContext $` Строка с текстом, размещенным слева от по- . следнего найденного соответствия шаблону var pattern = /(кот)-(пес)/g;
pattern.test(«это кот-пес и кот-пес»);
document.writeln(RegExp.leftContext);
// печатает «это»
document.writeln(RegExp[‘$`’]);
// печатает «это»
rightContext $’ Строка с текстом, размещенным справа от последнего найденного соответствия шаблону var pattern = /(кот)-(пес)/g;
pattern.test («это кот-пес и кот-пес»);
document.writeln(RegExp.rightContext);
// печатает «и кот-пес»
document.writeln(RegExp[‘$\’ ‘]) ;
// печатает «и кот-пес»

Интересным аспектом статических свойств класса RegExp является то, что они являются глобальными и, таким образом, изменяются каждый раз, когда вы используете регулярное выражение, как с методами String, так и с методами RegExp. По этой причине они являются исключением из правила, предусматривающего для JavaScript статический обзор данных. Для указанных свойств используется динамический обзор — т.е. изменения отражаются в объекте RegExp в контексте функции вызова, а не в контексте объемлющего исходного кода. Например, если в некотором фрейме вызывается функция, использующая регулярные выражения в другом фрейме, то JavaScript обновит статические свойства RegExp во фрейме вызова, а не во фрейме, где находится вызываемая функция. Это редко создает проблемы, но об этом необходимо помнить, когда статические свойства приходится использовать в окружении с фреймами.

Понравилась статья? Поделиться с друзьями:
Добавить комментарий