Регулярные выражения в JavaScript

Регулярные выражения JavaScript

Обработка текстовых данных является одной из типичных задач в JavaScript. Проверка вводимых в формы данных, построение и анализ файлов cookie, создание и модификация адресов URL и изменение содержимого Web-страниц — все эти задачи подразумевают выполнение множества операций со строками. Возможность сравнения и изменения текстовых данных в JavaScript обеспечивается объектом String, а также регулярными выражениями, которые позволяют использовать шаблоны символов и строк вместо явного указания последних.

Регулярные выражения имеют давнюю историю во многих операционных системах. Читателям, которые не знакомы с такими средствами UNIX, как grep, sed, awk и Perl, регулярные выражения могут поначалу казаться весьма странными и неудобными, но и такие читатели вскоре убедятся в их пользе.

Если вы когда-нибудь использовали команды dir в DOS или Is в UNIX, то вы, вероятно, использовали и «групповые символы» типа * или ?. Эти символы являются примитивными регулярными выражениями! Читателям, которые уже работали с регулярными выражениями, особенно в Perl, регулярные выражения JavaScript покажутся достаточно знакомыми.

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

Понятие регулярного выражения

Регулярное выражение задает шаблон символов. Можно, например, указать шаблон для рассмотренных выше телефонных номеров: три цифры, дефис, три цифры, дефис и еще четыре цифры. Ввиду предусмотренной гибкости регулярных выражений, можно указать шаблоны, в которых символ или группа символов повторяются нужное число раз, или шаблоны, в которых определенная последовательность символов появляется в указанном месте строки (например, в ее начале или конце).

Создав регулярное выражение (шаблон), вы можете сравнивать с ним строки. Это значит, что, сравнив регулярное выражение со строкой, вы узнаете, содержит ли эта строка данный шаблон. Например, одно регулярное выражение может быть шаблоном для действительных телефонных номеров, а другое — для адресов электронной почты. При вводе пользователем данных в форму можно с помощью регулярных выражений проверить соответствие введенных данных. Если введенные пользователем строки соответствуют шаблонам, можно продолжить обработку данных формы, а если не соответствуют, — прервать выполнение процедуры и обратить внимание пользователя на то, что данные введены неправильно. Мы увидим такие примеры использования регулярных выражений в главе 14, где будут обсуждаться Web-формы и проверка данных. Пока что мы выясним, как указать шаблоны, с которыми можно сравнивать строки, а чуть позже, — как решать более сложные задачи, например заменять часть строки, соответствующую данному шаблону.

Замечание. Термин «регулярное выражение» взят из той части информатики, которая связана с распознаванием языковых конструкций. Виды строк, которые можно распознать с помощью регулярных выражений, названы «регулярными»по той причине, что они очень просты с точки зрения распознавания их компьютером. Создать соответствующую программу сопоставления с образцом вручную просто, но весьма утомительно, поэтому мы предпочитаем только указать шаблон, а компьютер сначала генерирует, а затем выполняет соответствующий программный код распознавания.

Общие сведения о регулярных выражениях в JavaScript

Регулярные выражения появились в JavaScript 1.2 и JScript 3.0 вместе с объектом RegExp, поскольку соответствующие возможности реализуются посредством методов RegExp. Однако и многие методы объекта String допускают использование регулярных выражений в качестве аргументов, поэтому регулярные выражения часто встречаются в обоих указанных контекстах.

Обычно регулярные выражения создаются с помощью синтаксиса литералов, но символы, формирующие шаблон, ограничиваются знаками косой черты (/ и /). Например, чтобы создать регулярное выражение, которому будет соответствовать строка, содержащая «http», можно использовать следующую запись:

Этот шаблон читается так: за » h » следует » t», затем » t», а затем » р «. Этому шаблону будет соответствовать любая строка, содержащая «http». Непосредственно за второй косой чертой шаблона можно указать флаги, модифицирующие интерпретацию шаблона. Например, указать, что шаблон должен применяться без учета регистра, — для этого используется флаг i:

Здесь создается шаблон, которому будут соответствовать строки, содержащие как «http», так и «HTTP» или «HttP». Флаги, наиболее часто используемые с регулярными выражениями, показаны в табл. , а их применение будет иллюстрироваться в примерах данной главы. Пока что не беспокойтесь ни о чем, кроме i.

Символ Значение
i Нечувствительность к регистру
g Глобальное соответствие: находятся все случаи соответствия в строке, а не только первый
m Многострочное соответствие

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

Синтаксис конструктора часто используется тогда, когда шаблон, с которым сравниваются строки, остается не определенным до времени выполнения. Можно позволить ввести регулярное выражение пользователю, чтобы затем передать строку, содержащую полученное выражение, в конструктор RegExp(). Наиболее часто используемым методом объекта RegExp является test(). Этот метод возвращает логическое значение true или false, в зависимости от соответствия или несоответствия строки, переданной методу в виде аргумента, данному шаблону. Например, можете убедиться, что

возвратит false, поскольку шаблону соответствуют только строки, содержащие «http». Но можно проверить соответствие шаблону без учета регистра:

Тогда будет возвращено true, поскольку в данном случае поиск соответствия «http» в строке выполняется без учета регистра. Конечно, результата вы не увидите, пока не используете возвращаемое значение:

Автоматическое преобразование типов в JavaScript позволяет вызывать методы RegExp с литералами регулярных выражений (аналогично методам String с литералами строк). Например,

точно так же покажет true.

Необходимость регулярных выражений

Рассмотрим задачу проверки правильности ввода телефонного номера в форму на Web-странице. Перед тем как направить данные серверу для обработки, следует убедиться, что введенные данные имеют нужный формат. Например, если требуется обеспечить ввод телефонных номеров в формате NNN-NNN-NNNN, где N обозначает любую цифру, можно использовать следующий программный код:

Не слишком ли много программного кода для такой простой задачи? И этот программный код далек от совершенства, поэтому только представьте, насколько он усложнится, если придется проверять и другие форматы, например телефонные номера с добавочными кодами, международные номера или номера с пропущенными дефисами-разделителями.

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

С помощью регулярных выражений можно не только проверить соответствие строки конкретному шаблону (наподобие NNN-NNN-NNNN в предыдущем примере), но и в случае несоответствия можно найти, выделить и даже заменить фрагменты строки, частично соответствующие шаблону. Это значительно упрощает распознавание и извлечение структурированных данных типа адресов URL и электронной почты, телефонных номеров и файлов cookie.

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

Создание шаблонов

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

Индикаторы позиции

К первому множеству специальных символов можно отнести индикаторы позиции— это символы, указывающие требуемую позицию шаблона в строках, с которыми будет выполняться сравнение. Этими символами являются символы ^ и $, указывающие, соответственно, начало и конец строки. Например, шаблону var pattern = /^http/; будут соответствовать только те строки, которые начинаются с «http». Следующий оператор возвратит false:pattern.test(«Используется протокол http»);

Символ $ указывает противоположное поведение:

Этому шаблону будут соответствовать только те строки, которые заканчиваются на «http». Можно использовать оба индикатора позиции сразу, чтобы гарантировать точное соответствие нужному шаблону:

Это регулярное выражение читается так: «h» в начале строки, за ним следуют два «t», а затем «р» в конце строки. Этому шаблону соответствует только строка «http». При использовании индикаторов позиции в шаблонах следует проявлять особую аккуратность, чтобы не допустить соответствия шаблона непредусмотренным строкам.

Управляющие коды

С учетом предлагавшихся до сих пор вариантов синтаксиса литералов регулярных выражений возникает вопрос: как указать в шаблоне строку, включающую косую черту, например «http: / /www. w3c.org/»? Ответ будет следующим. Как и строки, регулярные выражения используют управляющие коды, чтобы указать символы, имеющие специальное значение. Управляющие коды указываются с помощью обратной косой черты (\). По сравнению с управляющими кодами, используемыми в строках, управляющие коды, используемые в регулярных выражениях, образуют более широкое множество (т.е. в регулярных выражениях гораздо больше символов имеют специальные значения, подобно символам ^ и $). Управляющие коды, о которых идет речь, приведены в табл. . Вам не придется запоминать их все, а их польза будет выясняться по мере нашего исследования возможностей регулярных выражений

Код Соответствие
\f Подача страницы
\п Переход на новую строку
Возврат каретки
\t Табуляция
\v Вертикальная табуляция
\/ Косая черта /
\\ Обратная косая черта \
\. . Точка
\* Звездочка *
\+ Знак плюс +
\? Знак вопроса ?
\| Символ конвейеризации |
\( Левая скобка (
\) Правая скобка)
\{ Левая квадратная скобка [
\] Правая квадратная скобка ]
\{ Левая фигурная скобка {
\} Правая фигурная скобка }
\000 ASCII-символ, представленный восьмеричным значением ООО
\хНН ASCII-символ, представленный шестнадцатеричным значением НН
\uHHHH Символ Unicode, представленный шестнадцатеричным значением НННН
\сХ Управляющий символ, представленный с помощью ^X. Например, \сH представляет CTRL+H

Используя подходящие управляющие коды, можно определить регулярное выражение, которому будет соответствовать строка «http://www.w3c.org/» (и любая другая строка, содержащая данную строку в качестве подстроки):

Ввиду того что символ / имеет специальное значение в литералах регулярных выражений (этот символ означает начало или конец шаблона), каждая косая черта (/) в шаблоне заменена ее эквивалентом \/.

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

Квантификаторы повторения

Квантификаторы повторения регулярных выражений позволяют указать число необходимых или возможных повторений конкретного элемента в выражении. Пока что считайте, что под «конкретным элементом» мы понимаем «предыдущий символ». Тонкости мы обсудим чуть позже. Так, квантификатор повторения * (звездочка) указывает, что предыдущий элемент может повторяться нуль или больше раз. В строках, соответствующих шаблону, может присутствовать любая последовательность нулевой или большей длины из повторяющихся элементов, соответствующих предыдущему элементу. Например:

Читайте * как «повторенное нуль или больше раз». В результате мы получаем шаблон, которому будут соответствовать строки, содержащие символ » а «, за которым сразу же следует символ «Ь», повторенный нуль или больше раз, а затем — «с». Все следующие строки будут соответствовать этому выражению:

  • ас
  • аbс
  • abbbbbbbbbbbbbbbbbbbbbbbbbbbc
  • С букв abc начинается английский алфавит

Точно так же + указывает, что предыдущий символ должен повторяться один или больше раз. Следующая декларацияvar pattern = /ab+с/;

читается как символ «а», за которым следует «b», повторенный один или больше раз, а затем — » с «. С учетом этого должно быть ясно, что данному шаблону соответствуют все следующие строки:

  • abc
  • abbbbbc
  • С букв abc начинается английский алфавит

А вот строка «ас» шаблону соответствовать не будет, поскольку данная строка не содержит ни одного «Ь» между «а» и «с».
Квантификатор ? указывает, что предыдущий элемент может не встречаться ни разу или встречаться один раз, но не более. Например:

Читайте это как «а», за которым следует нуль или одно «Ь», а затем — «с». Этому шаблону соответствует «ас» и «abc», но не «abbe». По сути, ? означает, что предыдущий элемент необязателен.
Квантификаторы повторения пока что не позволяют указать, что символ должен повторяться заданное число раз. Чтобы указать число повторений, позволенное для предшествующего символа, используются фигурные скобки ({ }). Например:

определяет шаблон, состоящий из символа «а», за которым следуют пять символов «Ь», а затем — «с». Конечно, это выражение можно также записать какvar pattern = /abbbbbc/;

но эта «длинная версия» оказывается слишком уж неуклюжей в тех случаях, когда приходится определять соответствие, скажем, 25 повторяющимся символам.
Использовать фигурные скобки можно и для того, чтобы указать, что число повторений должно находиться в пределах конкретного диапазона. Чтобы это сделать, в фигурных скобках указывается сначала минимально допустимое число повторений, а затем, через запятую, — максимально допустимое число повторений. Например:

определяет регулярное выражение, соответствующее одному символу «а», за которым следуют от пяти до семи (включительно) символов «Ь», а затем — «с».
Пропуск значения максимально допустимого числа повторений в фигурных скобках (но при наличии запятой) указывает минимальное число повторений. Например:

определяет регулярное выражение, соответствующее одному символу «а», за кот рым следуют не менее трех символов «Ь», а затем — «с».

Полный список квантификаторов повторения представлен в табл.

Символ Значение
* Предыдущий элемент встречается нуль или больше раз
+ Предыдущий элемент встречается как минимум один раз
? Предыдущий элемент встречается не более одного раза
{т,п} Предыдущий элемент встречается как минимум т раз, но не более п раз
{m,} Предыдущий элемент встречается как минимум m раз
{m} Предыдущий элемент встречается в точности т раз

Группирование

Обратите внимание на то, что в табл. для квантификаторов повторения указывается ссылка на «предыдущий элемент», который должен повторяться определенное число раз. В рассмотренных до сих пор примерах таким «предыдущим элементом» был один символ. Но JavaScript позволяет сгруппировать символы в один элемент, аналогично тому, как с помощью фигурных скобок можно группировать в блоки оператры. Проще всего группировать символы в регулярном выражении с помощью скобок. Любые символы, окруженные круглыми скобками, считаются в регулярном выражении отдельной единицей в отношении специальных операций. Например:

следует читать как символ «а», за которым следует пара «Ьс», повторенная как минимум один раз. Скобки группируют символы «Ь» и «с» относительно +. Этому шаблону будет соответствовать любая строка, содержащая «а» и как минимум одно «bc» после него.

Другим примером является

Этому шаблону соответствуют строки, содержащие слово «very», повторенное три четыре или пять раз, за которым следуют пробел и слово «hot».

Классы символов

Иногда необходимо учесть соответствие любому символу из группы допустимые Например, для проверки соответствия телефонным номерам такой группой символ » могут быть цифры, а если необходимо проверить название страны, группой допуст*-мых символов может быть алфавит.

JavaScript позволяет определить классы символов путем размещения допустим» символов в квадратных скобках ([ ]). В соответствующей строке может присутствовать любой символ из указанного класса, а сам класс считается отдельной единицей, подобно заключенным в круглые скобки группам.

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

В регулярном выражении запись [. . . ] обычно читается как «любой символ из группы», так что класс [pbm] ill можно прочитать как «р», «Ь» или «m», с последующими «ill». Этому шаблону соответствуют «pill», «billiard» и «paper mill», но не «chill».

Рассмотрим еще один пример:

Класс [123456789] содержит все цифры, и к нему применяется квантификатор +. В результате, шаблону будут соответствовать строки, содержащие как минимум одну цифру. Когда требуется задать большую группу допустимых символов, этот формат выглядит очень громоздко, но, к счастью, JavaScript позволяет использовать дефис (-), чтобы указать диапазон значений:

Это регулярное выражение является аналогом выражения из предыдущего примера, только записано более компактно. При использовании данной операции для диапазона указывается диапазон допустимых значений ASCII. Так что, например, с помощью

можно указать соответствие любой (латинской) букве нижнего регистра, а с помощью

можно указать соответствие любому буквенно-цифровому символу. JavaScript позволяет поместить в класс все символы из непрерывного диапазона ASCII, как в данном примере, и такой класс интерпретируется корректно. С помощью классов символов мы получаем, наконец, простой вариант шаблона для проверки телефонных номеров. Мы теперь можем переписать нашу функцию в виде

Этому шаблону соответствуют строки, содержащие любые три символа из класса цифр от 0 до 9 с последующим дефисом, затем еще три цифры и дефис, и еще четыре цифры. Сравните с тем, каким был наш программный код для проверки телефонных номеров в начале главы: без регулярных выражений нам потребовалось около 20 строк, а теперь — всего четыре! Можете убедиться, что указанная функция работает:

В результате мы получим:

Является ли 123456 номером телефона? false
Является ли 12-12-4322 номером телефона? false
Является ли 415-555-1212 номером телефона? true

Хотя наша функция isPhoneNumber(), на первый взгляд, работает прекрасно, она имеет скрытый недостаток, присущий всем указанным здесь регулярным выражениям, — позволяет слишком многое.

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

В результате вы увидите:

«true»;

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

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

В качестве еще одного примера применения регулярных выражений предлагаем шаблон для проверки имен пользователей (без учета регистра символов), начинающихся с буквы, за которой может либо не следовать ничего, либо любое количество буквенно-цифровых символов, а также символов подчеркивания или дефисов. Такой шаблон определяется следующим регулярным выражением:

Этому шаблону будут соответствовать, например, «m», «m10-120», «abracadabra» и «abra_cadabra», но не «_user» или «10аЬс». Обратите внимание на то, что дефис указан в определении класса последним, чтобы он не интерпретировался как операция диапазона.

Негативные классы символов

Квадратные скобки могут использоваться и для описания «негативных» классов : имволов, а именно классов, указывающих символы, которые не должны присутствовать в строке. Негативный класс указывается с помощью размещения знака вставки (л) в начале списка символов класса. Например, шаблону:

будет соответствовать любая последовательность из одного или более небуквенных (относительно латинского алфавита) символов, например «314», » ! ! %&^» или «__0». Строки, соответствующие указанному выражению, должны содержать как минимум эдин небуквенный символ.

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

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

Можете проверить, как этот шаблон работает:

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

Часто используемые классы символов

Часто используемым классам символов присвоены управляющие коды. Особенно полезным обозначением является точка — она используется для обозначения любого символа, кроме символа перехода на новую строку. Например, шаблону:

будут соответствовать «abcx7d» и «abc_-d». Другими общими классами являются \s (любой символ пустого пространства), \S (любой символ, не являющийся символом пустого пространства), \w (любой символ из тех, которые встречаются в словах), \w (любой символ из тех, которые не встречаются в словах), \d (любая цифра) и \D (любой символ, не являющийся цифрой). (Заметьте правило: версия в верхнем регистре является противоположностью версии в нижнем регистре).

Полный список классов символов представлен в табл.

Класс Значение
[символы] Любые символы в квадратных скобках, указанные либо явно, либо с помощью диапазона
[^символы] Любые символы, кроме символов в квадратных скобках, указанных либо явно, либо с помощью диапазона
. Любой символ, кроме символа перехода на новую строку
\w Символы слов. Эквивалентно [a-zA-Z0-9]
\W Символы, не являющиеся символами слов. Эквивалентно [Aa-zA-Z0-9 ]
\s Любые символы пустого пространства. Эквивалентно [ \t\n\r\f\v]
\S Любые символы, не являющиеся символами пустого пространства. Эквивалентно [^ \t\n\r\f\v ]
\d Любые цифры. Эквивалентно [0-9]
\D Любые символы, не являющиеся цифрами. Эквивалентно [^0-9]
\b Граница слов. «Пространство» между \w и \W
\B Не граница слов. Не «пространство» между символами слов
[\b] Символ возврата на одну позицию

С помощью этих сокращений можно записать еще более лаконичную версию функции isPhoneNumber():

Здесь мы просто заменили каждый класс [0-9] его сокращенным обозначением \d.

Альтернативы

К основным средствам определения шаблонов можно отнести и символ | — это знак альтернации, с помощью которого можно связать логическим ИЛИ несколько элементов. Например, чтобы проверить соответствие для строк, начинающихся с «ftp», «http» или «https», можно записать:

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

то полученному шаблону будут соответствовать строки, начинающиеся с «http», и строки, содержащие «ftp» или «https». Начальный символ А относится только к первому из альтернативных шаблонов. Для лучшего понимания сути рассмотрим следующее регулярное выражение:

Поскольку каждое | указывает новый шаблон, данному определению будут соответствовать строки, содержащие «Джеймс», «Джим» или «Чарли Браун», но не строки, включающие «Джеймс Браун», как можно было бы ожидать. Заключение альтернатив в круглые скобки ограничивает действие | на элементы внутри скобок, так что следующему шаблону:

уже будут соответствовать «Джеймс Браун», «Джим Браун» и «Чарли Браун».

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

Регулярное выражение Соответствующие строки Несоответствующие строки
/\Wten\W/ ten ten
tents
/\wten\w/ atenl ten
lten
/\bten\b/ ten attention
tensile
often
/\d(1,3)\.\d{1,3)\.\d{1,3}\.\d{1,3}/ 128.22.45.1 abc.44.55.42
128.22.45.
/^(http|ftp|https) :\/\/.*/ https://www.w3c.org
http://abc
file:///etc/motd
https//www.w3c.org
/\w+@\w+\.\w{l,3}/ presidentSwhitehouse.gov
president@white_house.us
[email protected]
presidents.gov
[email protected]
Понравилась статья? Поделиться с друзьями:
Добавить комментарий