5 практических примеров использования регулярных выражений на JavaScript


Оглавление (нажмите, чтобы открыть):

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

Введение в регулярные выражения

Регулярные выражения (RegExp) — это очень эффективный способ работы со строками.

Составив регулярное выражение с помощью специального синтаксиса вы можете:

  • искать текст в строке
  • заменять подстроки в строке
  • извлекать информацию из строки

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

Регулярные выражения относятся к 1950-м годам, когда они были формализованы как концептуальный шаблон поиска для алгоритмов обработки строк.

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

JavaScript, наряду с Perl, это один из языков программирования в котором поддержка регулярных выражений встроена непосредственно в язык.

Сложно, по полезно

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

Регулярные выражения сложно писать, сложно читать и сложно поддерживать/изменять.

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

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

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

Как выглядят регулярные выражения

В JavaScript регулярные выражения это объект, который может быть определён двумя способами.

Первый способ заключается в создании нового объекта RegExp с помощью конструктора:

Второй способ заключается в использовании литералов регулярных выражений:

Вы знаете что в JavaScript есть литералы объектов и литералы массивов? В нём также есть литералы regexp.

В приведённом выше примере hey называется шаблоном. В литеральной форме он находится между двумя слэшами, а в случае с конструктором объекта, нет.

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

Как они работают?

Регулярное выражение, которое мы определили выше как re1 , очень простое. Оно ищет строку hey без каки-либо ограничений: строка может содержать много текста, а слово hey находиться где-то в середине и регулярное выражение сработает. Строка может содержать только слово hey и регулярка опять сработает.

Это довольно просто.

Вы можете попробовать протестировать регулярное выражение с помощью метода RegExp.test(String) , который возвращает логическое ( boolean ) значение:

В примере выше мы просто проверили удовлетворяет ли «hey» шаблону регулярного выражения, который храниться в re1 .

Это проще простого, но вы уже знаете много о регулярных выражениях.

Закрепление

сработает независимо от того где находится hey внутри строки.

Если вы хотите найти строки, которые начинаются с hey , то используйте оператор ^ :

Если вы хотите найти строки, которые заканчиваются на hey , то используйте оператор $ :

Объединяя два предыдущих оператора вы можете найти строку, которая полностью совпадает с hey :

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

Поиск элементов по диапазону

Вместо того чтобы искать определённую строку, вы можете указать диапазон символов, например:

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

Диапазоны можно комбинировать:

Поиск многократных совпадений элемента диапазона

Вы можете проверить содержит ли строка только один символ из диапазона с помощью символа — :

Инверсия шаблона

Символ ^ в начале шаблона привязывает его к началу строки.

Использование этого символа внутри диапазона инвертирует диапазон, поэтому:

Метасимволы

  • \d совпадает с любым числом, эквивалентно [0-9]
  • \D совпадает с любым символом, который не является числом, эквивалентно [^0-9]
  • \w совпадает с любым буквенно-числовым символом, эквивалентно [A-Za-z0-9]
  • \W совпадает с любым символом, который не является буквенно-числовым значением, эквивалентно [^A-Za-z0-9]
  • \s совпадает с любым пробельным символом: пробел, табуляция, символ новой строки и пробелы Unicode
  • \S совпадает с любым символом, который не является пробелом
  • \0 совпадает с null
  • \n совпадает с символом новой строки
  • \t совпадает с символом табуляции
  • \uXXXX совпадает с символом Unicode с кодом XXXX (требуется флаг u )
  • . совпадает с любым символовом, кроме символа новой строки (таким как \n ) (если вы не используете флаг s , объясним позже)
  • [^] совпадает с любым символом, включая символ новой строки. Полезно при работе с многострочными строками

Выбор в регулярных выражениях

Если вы хотите выбрать одну или другую строку, используйте оператор | .

Квантификаторы

Представьте что у вас есть регулярное выражение, которое проверяет строку на то чтобы она состояла только из одной цифры:

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

но что если мы хотим чтобы регулярное выражение срабатывало на несколько цифр?

Вы можете сделать это 4 способами, используя + , * , и .

Совпадает с одним или более (>=1) элементами:

Совпадает с 0 или более (>=0) элементами:

Совпадает точно с n количеством элементов:

Совпадает с диапазоном от n до m элементов:

m можно опустить и оставить второй предел без ограничений, чтобы было минимум n элементов:

Опциональные элементы

Следующий за элементом знак ? , сделает его необязательным:

Группы

Используя круглые скобки, вы можете создавать группы символов (. ) .

Пример ниже ищет точное совпадение из 3 цифр за которым следует один или более буквенно-числовые символов:

Повторяющиеся символы, которые находятся после закрывающей группу скобки, относятся ко всей группе:

Захват групп

До сих пор мы видели, как тестировать строки и проверять, содержат ли они определенный шаблон.

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

Вы можете делать это с помощью групп, а точнее с помощью захвата групп.

По умолчанию, группы итак захватываются. Теперь вместо использования RegExp.test(String) , который просто возвращает логическое значение, мы будем использовать один из следующих методов:

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

Если совпадений не найдено, то он возвращает null .

Когда группа совпадает несколько раз, то только последнее найденное значение будет добавлено в возвращаемый массив.

Опциональные группы

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

Ссылка на найденную группу

Каждой найденной группе присваивается число. $1 ссылается на первый элемент, $2 на второй, и так далее. Это полезно, когда мы будет говорить о замене части строки.

Именованный захват групп

Это новая возможность ES2020.

Группе можно назначить имя, а не просто слот в возвращаемом массиве:

Использование match и exec без групп

Существует разница при использовании match и exec без групп: в первом элементе массива будет находится не полностью найденная строка, а прямое совпадение:

Незахватываемые группы

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

Флаги

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

  • g : ищет совпадения глобально
  • i : делает регулярное выражение не чувствительным к регистру
  • m : включает многострочный режим. В этом режиме ^ и $ совпадают с началом и концом всей строки. Без этого флага, с многострочными строками они совпадают с началом и концом каждой строки.
  • u : включает поддержку Unicode (добавлено в ES6/ES2015)
  • s : (новое в ES2020) сокращение от «single line», он позволяет . совпадать с символами новой строки

Флаги можно комбинировать, а также они добавляются в конец строки литерала:

или передаются вторым параметром в конструктор объекта RegExp:

Инспектирование регулярных выражений

Вы можете инспектировать свойства регулярных выражений:

  • source — строка шаблона
  • multiline — принимается значение true если установлен флаг m
  • global — принимается значение true если установлен флаг g
  • ignoreCase — принимается значение true если установлен флаг i
  • lastIndex

Экранирование

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

Границы строк

\b и \B позволяют определить находится ли строка в начале или конце слова:

  • \b совпадает если набор символов находится в начале или конце слова
  • \B совпадает если набор символов не находится в начале или конце слова

Замена с помощью регулярных выражений

Мы уже видели как нужно проверять строки на совпадение с шаблоном.

Также мы видели как можно извлекать часть строк соотвествующие шаблону в массив.

Теперь давайте рассмотрим как заменять части строки на основе шаблона.

У объекта String в JavaScript есть метод replace() , который можно использовать без регулярных выражений для одной замены в строке:

Этот метод также может принимать и регулярное выражение в качестве аргумента:

Использование флага g — это единственный способ заменить несколько вхождений в строке на ванильном JavaScript:

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

Вместо строки можно использовать функцию, чтобы делать ещё более интересные вещи. В неё будет передан ряд аргументов, таких как возвращают методы String.match(RegExp) или RegExp.exec(String) , где количество аргументов зависит от количества групп:

Жадность

Регулярные выражения называются жадными по умолчанию.

Возьмём например это регулярное выражение:

Предполагается, что нам нужно извлечь из строки сумму в долларах:

но что если у нас есть больше слов после числа, это отвлекает

Почему? Потому что регулярное выражение после знака $ совпадает с любым символом .+ и не останавливается пока не достигнет конца строки. Затем он останавливается, потому что \s? делает конечное пространство необязательным.

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

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

Опережение: соответствие строки в зависимости от того что за ней следует

Используйет ?= для поиска совпадений в строке за которой следует определённая подстрока

?! выполняет обратную операцию и находит совпадений в строке за которыми не следует определённая подстрока:

Ретроспектива: соответствие строки в зависимости от того что ей предшествует

Это новая возможность ES2020.

Опережение использует символ ?= . Ретроспектива использует ? :

Инверсия ретроспективы использует ? :

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

Флаг u является обязательным при работе с Unicode строками, в частности когда может понадобится обрабатывать строки в астральных плоскостях, которые не включены в первые 1600 символов Unicode.


Например эмодзи, но и только они.

Если вы не добавили этот флаг, то это просто регулярное выражение, которые должно найти совпадение одного символа, не будет работать, потому что для JavaScript этот эмодзи внутри представлен двумя символами:

Поэтому, всегда используйте флаг u .

Unicode, как и обычные символы, может обрабатывать диапазоны:

JavaScript проверяет внутренние коды представления, поэтому ? \u1F436 \u1F43A \u1F98A . Посмотрите полный список эмодзи чтобы увидеть коды и узнать их порядок.

Экранирование свойств Unicode

Как мы говорили выше, в шаблоне регулярного выражения вы можете использовать \d чтобы найти совпадение на любую цифру, \s чтобы найти совпадение на любой символ кроме пробела, \w чтобы найти совпадение на любой буквенно-числовой символ и т. д.

Экранирование свойств Unicode — это возможность ES2020, которая добавляет очень крутую функцию, расширяя эту концепцию на всех Unicode символы и добавляя \p<> и \P<> .

У любого Unicode символа есть набор свойств. Например Script определяет семейство языков, ASCII — это логическое значение равное true для ASCII символов и т.д. Вы можете положить это свойство в фигурные скобки и регулярное выражение будет проверять чтобы его значение было истинным:

ASCII_Hex_Digit — это ещё одно логическое свойство, которое проверяет содержит ли строка тольк валидные шестнадцатеричные цифры:

Существует много других логических свойств, которые вы можете проверить просто добавив их имя в фигурные скобки, включая Uppercase , Lowercase , White_Space , Alphabetic , Emoji и другие:

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

Прочитать больше обо всех свойствах вы можете здесь.

Примеры

Извлечение числа из строки

Предположим, что есть строка содержащая только одно число, которое нужно извлечь. /\d+/ должен сделать это:

Поиск E-mail адреса:

Простейший подход заключается в проверке безпробельных символов до и после знака @ , с помощью \S :

Однако, это упрощенный пример, так как под него попадает множество не валидных E-mail адресов.

Захват текста между двойными кавычками

Представим, что у вас есть строка, которая содержит текст заключённый в двойные кавычки и вам нужно извлечь этот текст.

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

Мы найдём то что нам нужно в result[1] :

Получение содержимого из HTML тега

Например получить содержимое из тега span , допуская при этом любое количество аргументов у тега:

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

— это объект, описывающий символьный шаблон. Класс RegExp в JavaScript представляет регулярные выражения, а объекты классов String и RegExp определяют методы, использующие регулярные выражения для выполнения поиска по шаблону и операций поиска в тексте с заменой. Грамматика регулярных выражений в языке JavaScript содержит достаточно полное подмножество синтаксиса регулярных выражений, используемого в языке Perl 5, поэтому, если вы имеете опыт работы с языком Perl, то вы без труда сможете описывать шаблоны в программах на языке JavaScript.

В число особенностей регулярных выражений языка Perl, которые не поддерживаются в ECMAScript, входят флаги s (однострочный режим) и x (расширенный синтаксис); управляющие последовательности \a, \e, \l, \u, \L, \U, \E, \Q, \A, \Z, \z и \G и другие расширенные конструкции, начинающиеся с (?.

Определение регулярных выражений

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

Эта строка создает новый объект RegExp и присваивает его переменной pattern. Данный объект RegExp ищет любые строки, заканчивающиеся символом «s». Это же регулярное выражение может быть определено с помощью конструктора RegExp():

Спецификация шаблона регулярного выражения состоит из последовательности символов. Большая часть символов, включая все алфавитно-цифровые, буквально описывают символы, которые должны присутствовать. То есть регулярное выражение /java/ совпадает со всеми строками, содержащими подстроку «java».

Другие символы в регулярных выражениях не предназначены для поиска их точных эквивалентов, а имеют особое значение. Например, регулярное выражение /s$/ содержит два символа. Первый символ s обозначает поиск буквального символа. Второй, $ — это специальный метасимвол, обозначающий конец строки. Таким образом, это регулярное выражение соответствует любой строке, заканчивающейся символом s.

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

Символы литералов

Как отмечалось ранее, все алфавитные символы и цифры в регулярных выражениях соответствуют сами себе. Синтаксис регулярных выражений в JavaScript также поддерживает возможность указывать некоторые неалфавитные символы с помощью управляющих последовательностей, начинающихся с символа обратного слэша (\). Например, последовательность \n соответствует символу перевода строки. Эти символы перечислены в таблице ниже:

Символы в регулярных выражениях JavaScript

Символ Соответствие
Алфавитно-цифровые символы Соответствуют сами себе
\0 Символ NUL (\u0000)
\t Табуляция (\u0009)
\n Перевод строки (\u000A)
\v Вертикальная табуляция (\u000B)
\f Перевод страницы (\u000C)
\r Возврат каретки (\u000D)
\xnn Символ из набора Latin, задаваемый шестнадцатеричным числом nn; например, \x0A — это то же самое, что \n
\uxxxx Unicode-символ, заданный шестнадцатеричным числом xxxx; например, \u0009 — это то же самое, что \t
\cX Управляющий символ «X», например, последовательность \cJ эквивалентна символу перевода строки \n

Некоторые знаки препинания имеют в регулярных выражениях особый смысл:

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

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

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

Отдельные символы литералов могут объединяться в классы символов путем помещения их в квадратные скобки. Класс символов соответствует любому символу, содержащемуся в этом классе. Следовательно, регулярное выражение /[abc]/ соответствует одному из символов a, b или c.

Могут также определяться классы символов с отрицанием, соответствующие любому символу, кроме тех, которые указаны в скобках. Класс символов с отрицанием задается символом ^ в качестве первого символа, следующего за левой скобкой. Регулярное выражение /[^abc]/ соответствует любому символу, отличному от a, b или c. В классах символов диапазон символов может задаваться при помощи дефиса. Поиск всех символов латинского алфавита в нижнем регистре осуществляется посредством выражения /[a-z]/, а любую букву или цифру из набора символов Latin можно найти при помощи выражения /[a-zA-Z0-9]/.

Некоторые классы символов используются особенно часто, поэтому синтаксис регулярных выражений в JavaScript включает специальные символы и для их обозначения. Так, \s соответствует символам пробела, табуляции и любым пробельным символам из набора Unicode, а \S — любым символам, не являющимся пробельными символами из набора Unicode.

В таблице ниже приводится перечень этих спецсимволов и синтаксиса классов символов. (Обратите внимание, что некоторые из управляющих последовательностей классов символов соответствуют только ASCII-символам и не расширены для работы с Unicode-символами. Можно явно определить собственные классы Unicode-символов, например, выражение /[\u0400-\u04FF]/ соответствует любому символу кириллицы.)

Классы символов регулярных выражений JavaScript

Символ Соответствие
[. ] Любой из символов, указанных в скобках
[^. ] Любой из символов, не указанных в скобках
. Любой символ, кроме перевода строки или другого разделителя Unicode-строки
\w Любой текстовый ASCII-символ. Эквивалентно [a-zA-Z0-9_]
\W Любой символ, не являющийся текстовым ASCII-символом. Эквивалентно [^a-zA-Z0-9_]
\s Любой пробельный символ из набора Unicode
\S Любой непробельный символ из набора Unicode. Обратите внимание, что символы \w и \S — это не одно и то же
\d Любые ASCII-цифры. Эквивалентно [0-9]
\D Любой символ, отличный от ASCII-цифр. Эквивалентно [^0-9]
[\b] Литерал символа «забой»

Обратите внимание, что управляющие последовательности специальных символов классов могут находиться в квадратных скобках. \s соответствует любому пробельному символу, а \d соответствует любой цифре, следовательно, /[\s\d]/ соответствует любому пробельному символу или цифре.

Повторение

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

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

Символы повторения в регулярных выражениях JavaScript

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

Следующие строки демонстрируют несколько примеров:

Будьте внимательны при использовании символов повторения * и ?. Они могут соответствовать отсутствию указанного перед ними шаблона и, следовательно, отсутствию символов. Например, регулярному выражению /a*/ соответствует строка «bbbb», поскольку в ней нет символа a.

Символы повторения, перечисленные в таблице, соответствуют максимально возможному количеству повторений, при котором обеспечивается поиск последующих частей регулярного выражения. Мы говорим, что это — «жадное» повторение. Имеется также возможность реализовать повторение, выполняемое «нежадным» способом. Достаточно указать после символа (или символов) повторения вопросительный знак: . +?, *? или даже <1,5>?.

Например, регулярное выражение /a+/ соответствует одному или более экземплярам буквы a. Примененное к строке «aaa», оно соответствует всем трем буквам. С другой стороны, выражение /a+?/ соответствует одному или более экземплярам буквы a и выбирает наименее возможное число символов. Примененный к той же строке, этот шаблон соответствует только первой букве a.

«Нежадное» повторение не всегда дает ожидаемый результат. Рассмотрим шаблон /a+b/, соответствующий одному или более символам a, за которыми следует символ b. Применительно к строке «aaab» ему соответствует вся строка.

Теперь проверим «нежадную» версию /a+?b/. Можно было бы подумать, что она должна соответствовать символу b, перед которым стоит только один символ a. В случае применения к той же строке «aaab» можно было бы ожидать, что она совпадет с единственным символом a и последним символом b. Однако на самом деле этому шаблону соответствует вся строка, как и в случае «жадной» версии. Дело в том, что поиск по шаблону регулярного выражения выполняется путем нахождения первой позиции в строке, начиная с которой соответствие становится возможным. Так как соответствие возможно, начиная с первого символа строки, более короткие соответствия, начинающиеся с последующих символов, даже не рассматриваются.

Альтернативы, группировка и ссылки

Грамматика регулярных выражений включает специальные символы определения альтернатив, подвыражений группировки и ссылок на предыдущие подвыражения. Символ вертикальной черты | служит для разделения альтернатив. Например, /ab|cd|ef/ соответствует либо строке «ab», либо строке «cd», либо строке «ef», а шаблон /\d<3>|[a-z]<4>/ — либо трем цифрам, либо четырем строчным буквам.

Обратите внимание, что альтернативы обрабатываются слева направо до тех пор, пока не будет найдено соответствие. При обнаружении совпадения с левой альтернативой правая игнорируется, даже если можно добиться «лучшего» соответствия. Поэтому, когда к строке «ab» применяется шаблон /a|ab/, он будет соответствовать только первому символу.

Круглые скобки имеют в регулярных выражениях несколько значений. Одно из них — группировка отдельных элементов в одно подвыражение, так что элементы при использовании специальных символов |, *, +, ? и других рассматриваются как одно целое. Например, шаблон /java(script)?/ соответствует слову «java», за которым следует необязательное слово «script», а /(ab|cd)+|ef)/ соответствует либо строке «ef», либо одному или более повторений одной из строк «ab» или «cd».

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

Предположим, что требуется отыскать одну или более букв в нижнем регистре, за которыми следует одна или несколько цифр. Для этого можно воспользоваться шаблоном /[a-z]+\d+/. Но предположим также, что нам нужны только цифры в конце каждого соответствия. Если поместить эту часть шаблона в круглые скобки (/[a-z]+(\d+)/), то можно будет извлечь цифры из любых найденных нами соответствий. Как это делается, будет описано ниже.

С этим связано еще одно применение подвыражений в скобках, позволяющее ссылаться на подвыражения из предыдущей части того же регулярного выражения. Это достигается путем указания одной или нескольких цифр после символа \. Цифры ссылаются на позицию подвыражения в скобках внутри регулярного выражения. Например, \1 ссылается на первое подвыражение, а \3 — на третье. Обратите внимание, что подвыражения могут быть вложены одно в другое, поэтому при подсчете используется позиция левой скобки. Например, в следующем регулярном выражении ссылка на вложенное подвыражение ([Ss]cript) будет выглядеть как \2:

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

Соответствия кавычек мы можем потребовать посредством такой ссылки:

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

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

Здесь подвыражение (?:[Ss]cript) необходимо только для группировки, чтобы к группе мог быть применен символ повторения ?. Эти модифицированные скобки не создают ссылку, поэтому в данном регулярном выражении \2 ссылается на текст, соответствующий шаблону (fun\w*).

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

Символы регулярных выражений выбора из альтернатив, группировки и ссылки JavaScript

Символ Значение
| Альтернатива. Соответствует либо подвыражению слева, либо подвыражению справа.
(. ) Группировка. Группирует элементы в единое целое, которое может использоваться с символами *, +, ?, | и т.п. Также запоминает символы, соответствующие этой группе для использования в последующих ссылках.
(. ) Только группировка. Группирует элементы в единое целое, но не запоминает символы, соответствующие этой группе.
\number Соответствует тем же символам, которые были найдены при сопоставлении с группой с номером number. Группы — это подвыражения внутри скобок (возможно, вложенных). Номера группам присваиваются путем подсчета левых скобок слева направо. Группы, сформированные с помощью символов (. не нумеруются.

Указание позиции соответствия

Как описывалось ранее, многие элементы регулярного выражения соответствуют одному символу в строке. Например, \s соответствует одному пробельному символу. Другие элементы регулярных выражений соответствуют позициям между символами, а не самим символам. Например, \b соответствует границе слова — границе между \w (текстовый ASCII-символ) и \W (нетекстовый символ) или границе между текстовым ASCII-символом и началом или концом строки.

Такие элементы, как \b, не определяют какие-либо символы, которые должны присутствовать в найденной строке, однако они определяют допустимые позиции для проверки соответствия. Иногда эти элементы называются якорными элементами регулярных выражений, потому что они закрепляют шаблон за определенной позицией в строке. Чаще других используются такие якорные элементы, как ^ и $, привязывающие шаблоны соответственно к началу и концу строки.

Например, слово «JavaScript», находящееся на отдельной строке, можно найти с помощью регулярного выражения /^JavaScript$/. Чтобы найти отдельное слово «Java» (а не префикс, например в слове «JavaScript»), можно попробовать применить шаблон /\sJava\s/, который требует наличия пробела до и после слова.

Но такое решение порождает две проблемы. Во-первых, оно найдет слово «Java», только если оно окружено пробелами с обеих сторон, и не сможет найти его в начале или в конце строки. Во-вторых, когда этот шаблон действительно найдет соответствие, возвращаемая им строка будет содержать ведущие и замыкающие пробелы, а это не совсем то, что нам нужно. Поэтому вместо шаблона, совпадающего с пробельными символами \s, мы воспользуемся шаблоном (или якорем), совпадающим с границами слова \b. Получится следующее выражение: /\bJava\b/.

Якорный элемент \B соответствует позиции, не являющейся границей слова. То есть шаблону /\B[Ss]cript/ будут соответствовать слова «JavaScript» и «postscript» и не будут соответствовать слова «script» или «Scripting».

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

Например, чтобы найти совпадение с названием распространенного языка программирования, за которым следует двоеточие, можно воспользоваться выражением /[Jj]ava([Ss]cript)?(?=\:)/. Этому шаблону соответствует слово «JavaScript» в строке «JavaScript: The Definitive Guide», но ему не будет соответствовать слово «Java» в строке «Java in a Nutshell», потому что за ним не следует двоеточие.

Если же ввести условие (. то это будет негативная опережающая проверка на последующие символы, требующая, чтобы следующие символы не соответствовали указанному шаблону. Например, шаблону /Java(?!Script)([A — Z]\w*)/ соответствует подстрока «Java», за которой следует заглавная буква и любое количество текстовых ASCII-символов при условии, что за подстрокой «Java» не следует подстрока «Script». Он совпадет со строкой «JavaBeans», но не совпадет со строкой «Javanese», совпадет со строкой «JavaScrip», но не совпадет со строками «JavaScript» или «JavaScripter».

В таблице ниже приводится перечень якорных символов регулярных выражений:

Якорные символы регулярных выражений

Символ Значение
^ Соответствует началу строкового выражения или началу строки при многострочном поиске.
$ Соответствует концу строкового выражения или концу строки при многострочном поиске.
\b Соответствует границе слова, т.е. соответствует позиции между символом \w и символом \W или между символом \w и началом или концом строки. (Однако обратите внимание, что [\b] соответствует символу забоя.)
\B Соответствует позиции, не являющейся границей слов.
(?=p) Позитивная опережающая проверка на последующие символы. Требует, чтобы последующие символы соответствовали шаблону p, но не включает эти символы в найденную строку.
(?!p) Негативная опережающая проверка на последующие символы. Требует, чтобы следующие символы не соответствовали шаблону p.

Флаги

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

Флаг i указывает, что поиск по шаблону должен быть нечувствителен к регистру символов, а флаг g — что поиск должен быть глобальным, т.е. должны быть найдены все соответствия в строке. Флаг m выполняет поиск по шаблону в многострочном режиме. Если строковое выражение, в котором выполняется поиск, содержит символы перевода строк, то в этом режиме якорные символы ^ и $, помимо того, что они соответствуют началу и концу всего строкового выражения, также соответствуют началу и концу каждой текстовой строки. Например, шаблону /java$/im соответствует как слово «java», так и «Java\nis fun».

Эти флаги могут объединяться в любые комбинации. Например, чтобы выполнить поиск первого вхождения слова «java» (или «Java», «JAVA» и т.д.) без учета регистра символов, можно воспользоваться нечувствительным к регистру регулярным выражением /\bjava\b/i. А чтобы найти все вхождения этого слова в строке, можно добавить флаг g: /\bjava\b/gi.

Методы класса String для поиска по шаблону

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

Строки поддерживают четыре метода, использующие регулярные выражения. Простейший из них — метод search(). Он принимает в качестве аргумента регулярное выражение и возвращает либо позицию первого символа найденной подстроки, либо -1, если соответствие не найдено. Например, следующий вызов вернет 4:

Если аргумент метода search() не является регулярным выражением, он сначала преобразуется путем передачи конструктору RegExp. Метод search() не поддерживает глобальный поиск и игнорирует флаг g в своем аргументе.

Метод replace() выполняет операцию поиска с заменой. Он принимает в качестве первого аргумента регулярное выражение, а в качестве второго — строку замены. Метод отыскивает в строке, для которой он вызван, соответствие указанному шаблону.

Если регулярное выражение содержит флаг g, метод replace() заменяет все найденные совпадения строкой замены. В противном случае он заменяет только первое найденное совпадение. Если первый аргумент метода replace() является строкой, а не регулярным выражением, то метод выполняет буквальный поиск строки, а не преобразует его в регулярное выражение с помощью конструктора RegExp(), как это делает метод search().

В качестве примера мы можем воспользоваться методом replace() для единообразной расстановки прописных букв в слове «JavaScript» для всей строки текста:

Метод replace() представляет собой более мощное средство, чем можно было бы предположить по этому примеру. Напомню, что подвыражения в скобках, находящиеся внутри регулярного выражения, нумеруются слева направо, и что регулярное выражение запоминает текст, соответствующий каждому из подвыражений. Если в строке замены присутствует знак $ с цифрой, метод replace() заменяет эти два символа текстом, соответствующим указанному подвыражению. Это очень полезная возможность. Мы можем использовать ее, например, для замены прямых кавычек в строке типографскими кавычками, которые имитируются ASCII-символами:

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

Метод match() — это наиболее общий из методов класса String, использующих регулярные выражения. Он принимает в качестве единственного аргумента регулярное выражение (или преобразует свой аргумент в регулярное выражение, передав его конструктору RegExp()) и возвращает массив, содержащий результаты поиска. Если в регулярном выражении установлен флаг g, метод возвращает массив всех соответствий, присутствующих в строке. Например:

Если регулярное выражение не содержит флаг g, метод match() не выполняет глобальный поиск; он просто ищет первое совпадение. Однако match() возвращает массив, даже когда метод не выполняет глобальный поиск. В этом случае первый элемент массива — это найденная подстрока, а все оставшиеся элементы представляют собой подвыражения регулярного выражения. Поэтому если match() возвращает массив arr, то arr[0] будет содержать найденную строку целиком, arr[1] -подстроку, соответствующую первому подвыражению, и т.д. Проводя параллель с методом replace(), можно сказать, что в arr[n] заносится содержимое $n.

Например, взгляните на следующий программный код, выполняющий разбор URL-адреса:

Следует отметить, что для регулярного выражения, в котором не установлен флаг g глобального поиска, метод match() возвращает то же значение, что и метод exec() регулярного выражения: возвращаемый массив имеет свойства index и input, как описывается в обсуждении метода exec() ниже.

Последний из методов объекта String, в котором используются регулярные выражения — split(). Этот метод разбивает строку, для которой он вызван, на массив подстрок, используя аргумент в качестве разделителя. Например:

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

Объект RegExp

Как было упомянуто, регулярные выражения представлены в виде объектов RegExp. Помимо конструктора RegExp(), объекты RegExp поддерживают три метода и несколько свойств.

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

Второй аргумент RegExp() может отсутствовать. Если он указан, то определяет флаги регулярного выражения. Это должен быть один из символов g, i, m либо комбинация этих символов. Например:

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

Свойства RegExp

Каждый объект RegExp имеет пять свойств. Свойство source — строка, доступная только для чтения, содержащая текст регулярного выражения. Свойство global — логическое значение, доступное только для чтения, определяющее наличие флага g в регулярном выражении. Свойство ignoreCase — это логическое значение, доступное только для чтения, определяющее наличие флага i в регулярном выражении. Свойство multiline — это логическое значение, доступное только для чтения, определяющее наличие флага m в регулярном выражении. И последнее свойство lastIndex — это целое число, доступное для чтения и записи. Для шаблонов с флагом g это свойство содержит номер позиции в строке, с которой должен быть начат следующий поиск. Как описано ниже, оно используется методами exec() и test().

Методы RegExp

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

Метод exec() выполняет регулярное выражение для указанной строки, т.е. ищет совпадение в строке. Если совпадение не найдено, метод возвращает null. Однако если соответствие найдено, он возвращает такой же массив, как массив, возвращаемый методом match() для поиска без флага g. Нулевой элемент массива содержит строку, соответствующую регулярному выражению, а все последующие элементы — подстроки, соответствующие всем подвыражениям. Кроме того, свойство index содержит номер позиции символа, которым начинается соответствующий фрагмент, а свойство input ссылается на строку, в которой выполнялся поиск.

В отличие от match(), метод exec() возвращает массив, структура которого не зависит от наличия в регулярном выражении флага g. Напомню, что при передаче глобального регулярного выражения метод match() возвращает массив найденных соответствий. А exec() всегда возвращает одно соответствие, но предоставляет о нем полную информацию. Когда exec() вызывается для регулярного выражения, содержащего флаг g, метод устанавливает свойство lastIndex объекта регулярного выражения равным номеру позиции символа, следующего непосредственно за найденной подстрокой.

Когда метод exec() вызывается для того же регулярного выражения второй раз, он начинает поиск с символа, позиция которого указана в свойстве lastIndex. Если exec() не находит соответствия, свойство lastIndex получает значение 0. (Вы также можете установить lastIndex в ноль в любой момент, что следует делать во всех тех случаях, когда поиск завершается до того, как будет найдено последнее соответствие в одной строке, и начинается поиск в другой строке с тем же объектом RegExp.) Это особое поведение позволяет вызывать exec() повторно для перебора всех соответствий регулярному выражению в строке. Например:

Еще один метод объекта RegExp — test(), который намного проще метода exec(). Он принимает строку и возвращает true, если строка соответствует регулярному выражению:

Вызов test() эквивалентен вызову exec(), возвращающему true, если exec() возвращает не null. По этой причине метод test() ведет себя так же, как метод exec() при вызове для глобального регулярного выражения: он начинает искать указанную строку с позиции, заданной свойством lastIndex, и если находит соответствие, устанавливает свойство lastIndex равным номеру позиции символа, непосредственно следующего за найденным соответствием. Поэтому с помощью метода test() можно так же сформировать цикл обхода строки, как с помощью метода exec().

Регулярные выражения JavaScript — шпаргалка

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

Объявление регулярных выражений в JavaScript

В JavaScript существует 2 способа объявления регулярных выражений.

var rgx = /^(\d+)/ – вы можете создать переменную и в качестве значения сохранить в нее шаблон регулярного выражения.

var rgx = new RegExp(‘^(\d+)’) – функция-конструктор полезна, когда необходимо изменять регулярное выражение программно. В данном случае регулярное выражение создается во время выполнения программы.

Соответствие определенному набору символов

Следующие спецсимволы используются для определения соответствия определенному набору символов.

\w – Соответствует буквенному или цифровому символу, а также знаку подчёркивания

\W – Соответствует любому символу, за исключением буквенного, цифрового и знака подчеркивания.

\d – Соответствует цифровому символу. Любые цифры от 0 до 9

\D – Соответствует не цифровому символу. Любые символы за исключением цифр от 0 до 9

\s – Соответствует пробельным символам. К ним относятся: пробел, табуляция и перевод строки

\S – Все символы за исключением пробельных

. – Соответствует любому символу за исключением перевода строки

[A-Z] – Обозначает диапазон символов. Например, выражение [A-E] – соответствует символам “A”, “B”, “C”, “D” и “E”

[ABC] – Соответствует перечисленным в символам в выражении. Например, [AMT] – сработает только с символами “A”, “M” и “T”.

[^ABC] – Соответствует символам, не представленным в выражении. Например, с помощью [^A-E] найдутся все символы за исключением, “A”, “B”, “C”, “D” и “E”.

Указание количества повторений символов в тексте

Все приведенные выше регулярные выражения будут совпадать только с одним символом. Чтобы указать, сколько символов должно быть тексте, чтобы произошло совпадение вы можете использовать квантификаторы .

+ – Обозначает одно или более совпадение. Например, чтобы регулярное выражение совпало с набором символов “ABD12D” нужно использовать \w+ .

* – Обозначает ноль или более символов. Например, под выражение b\w* подойдут следующие сочетания символов: “b” , “bat” , “bajhdsfbfjhbe” . В данном случае мы ищем соответствие нулевому или более количеству символов в словах после буквы “b”.


– Соответствует не менее m и не более n вхождений предыдущего символа. будет соответствовать не менее, чем m вхождений, верхнего предела в этом случае нет. будет соответствовать точному количеству (k) вхождений предыдущего символа.

? – Обозначает ноль или один символ. Например, это может быть полезно при сопоставлении двух вариантов написания для одной и той же слова. Выражению будут соответствовать оба слова: “behavior” и “behaviour” .

| – Соответствует выражению до или после символа |. Например, выражению /se(a|e)/ — соответсвуют оба слова: “see” и “sea” .

Группировка в регулярных выражениях

(ABC) – Объединение несколько символов вместе. Подстрока, соответствующую этому выражению сохраняется для последующего использования.

(?:ABC) – Это выражение также производит поиск группы символов, но не сохраняет результат.

\d+(?=ABC) – выражение соответствует символам предшествующим (?=ABC) , только если за ним следует “ABC”. Часть “ABC” не будет учитываться при поиске. Часть выражения “\d” приведена всего лишь для примера. На ее месте может быть любое регулярное выражение.

\d+(?!ABC) – выражение соответствует символам предшествующим (?!ABC) , только если за ним НЕ следует “ABC”. Часть “ABC” не будет учитываться при поиске. Часть выражения “\d” приведена всего лишь для примера. На ее месте может быть любое регулярное выражение.

Другие символы регулярных выражений

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

^ – Указывает на начало строки;

$ – Указывает на конец строки;

\b – Соответствует символу, если предыдущий символ является границей слова;

\B – Соответствует символу, если предыдущий символ не является границей слова;

Используем флаги в регулярных выражениях

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

g – находятся все совпадения с указанным выражением в тексте(глобальный поиск);

i – делает поиск нечувствительным к регистру. В этом случае такие слова, как “Apple” , “aPPLe” и “apple” попадут в результаты поиска;

m – флаг включает многострочный поиск;

u – этот флаг позволит вам использовать в вашем регулярном выражении escape-последовательности кода Unicode;

y – Указывает JavaScript вести поиск соответствия в текущей позиции в целевой строке;

Флаги для регулярного выражения в JavaScript можно использовать 2 способами: либо путем добавления их в конец литерала регулярных выражений, либо путем передачи их в конструктор RegExp. Например, /cat/i , соответствующее всех вхождениям слова “cat” независимо от регистра и RegExp(«cat», ‘i’) будут работать одинаково.

Полезные методы работы с регулярными выражениями в JavaScript

Регулярные выражения, создаваемые с использованием флагов и последовательностей символов, которые мы обсуждали ранее в этой статье, предназначены для использования с различными методами JavaScript для поиска, замены или разделения строк.

Вот некоторые методы, связанные с регулярными выражениями.

► test() – проверяет, содержит ли основная строка подстроку, которая соответствует шаблону, заданному данным регулярным выражением. При успешном совпадении метод возвращает true , в противном случае — false .

В приведённом выше примере приведено регулярное выражение, предназначенное для поиска слова “apples” в случае, если оно расположено в конце строки. Поэтому в первом случае метод вернет false .

► search() – проверяет, содержит ли основная строка подстроку, которая соответствует шаблону, заданному данным регулярным выражением. Метод возвращает индекс совпадения при успехе и -1 в противном случае.

В данном примере проверка по превому регулярному выражению вернет -1 , потому что не указан флаг нечувствительности к регистру.

► match() – осуществляет поиск подстроки в основной строке. Подстрока должна соответствовать шаблону, заданному данным регулярным выражением. Если используется флаг g , то несколько совпадений будут возвращены в виде массива.

► exec() – производит поиск подстроки в основной строке. В случае, если подстрока соответствует шаблону, заданному данным регулярным выражением, возвращает массив с результатами или null . В свойстве input хранится оригинальная строка

► replace() – ищет подстроку, соответствующую заданному шаблону и заменяет ее на предоставленную заменяющую строку.

► split() – Этот метод позволит вам разбить основную строку на подстроки на основе разделителя, представленного в виде регулярного выражения.

Заключение

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

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

Регулярные выражения для новичков

Задачи и их разборы с javascript.ru; в статье использованы комиксы xkcd.

Что такое регулярные выражения?

Если вам когда-нибудь приходилось работать с командной строкой, вы, вероятно, использовали маски имён файлов. Например, чтобы удалить все файлы в текущей директории, которые начинаются с буквы “d”, можно написать rm d* .

Регулярные выражения представляют собой похожий, но гораздо более сильный инструмент для поиска строк, проверки их на соответствие какому-либо шаблону и другой подобной работы. Англоязычное название этого инструмента — Regular Expressions или просто RegExp. Строго говоря, регулярные выражения — специальный язык для описания шаблонов строк.

Реализация этого инструмента различается в разных языках программирования, хоть и не сильно. В данной статье мы будем ориентироваться в первую очередь на реализацию Perl Compatible Regular Expressions.

Основы синтаксиса

В первую очередь стоит заметить, что любая строка сама по себе является регулярным выражением. Так, выражению Хаха , очевидно, будет соответствовать строка “Хаха” и только она. Регулярные выражения являются регистрозависимыми, поэтому строка “хаха” (с маленькой буквы) уже не будет соответствовать выражению выше.

4 октября 2020 – 1 марта 2020, Москва и онлайн, беcплатно

Однако уже здесь следует быть аккуратным — как и любой язык, регулярные выражения имеют спецсимволы, которые нужно экранировать. Вот их список: . ^ $ * + ? < >[ ] \ | ( ) . Экранирование осуществляется обычным способом — добавлением \ перед спецсимволом.

Набор символов

Предположим, мы хотим найти в тексте все междометия, обозначающие смех. Просто Хаха нам не подойдёт — ведь под него не попадут “Хехе”, “Хохо” и “Хихи”. Да и проблему с регистром первой буквы нужно как-то решить.

Здесь нам на помощь придут наборы — вместо указания конкретного символа, мы можем записать целый список, и если в исследуемой строке на указанном месте будет стоять любой из перечисленных символов, строка будет считаться подходящей. Наборы записываются в квадратных скобках — паттерну [abcd] будет соответствовать любой из символов “a”, “b”, “c” или “d”.

Внутри набора большая часть спецсимволов не нуждается в экранировании, однако использование \ перед ними не будет считаться ошибкой. По прежнему необходимо экранировать символы “\” и “^”, и, желательно, “]” (так, [][] обозначает любой из символов “]” или «[», тогда как [[]х] – исключительно последовательность “[х]”). Необычное на первый взгляд поведение регулярок с символом “]” на самом деле определяется известными правилами, но гораздо легче просто экранировать этот символ, чем их запоминать. Кроме этого, экранировать нужно символ «-», он используется для задания диапазонов (см. ниже).

Если сразу после [ записать символ ^ , то набор приобретёт обратный смысл — подходящим будет считаться любой символ кроме указанных. Так, паттерну [^xyz] соответствует любой символ, кроме, собственно, “x”, “y” или “z”.

Итак, применяя данный инструмент к нашему случаю, если мы напишем [Хх][аоие]х[аоие] , то каждая из строк “Хаха”, “хехе”, “хихи” и даже “Хохо” будут соответствовать шаблону.

Предопределённые классы символов

Для некоторых наборов, которые используются достаточно часто, существуют специальные шаблоны. Так, для описания любого пробельного символа (пробел, табуляция, перенос строки) используется \s , для цифр — \d , для символов латиницы, цифр и подчёркивания “_” — \w .

Если необходимо описать вообще любой символ, для этого используется точка — . . Если указанные классы написать с заглавной буквы ( \S , \D , \W ) то они поменяют свой смысл на противоположный — любой непробельный символ, любой символ, который не является цифрой, и любой символ кроме латиницы, цифр или подчёркивания соответственно.

Также с помощью регулярных выражений есть возможность проверить положение строки относительно остального текста. Выражение \b обозначает границу слова, \B — не границу слова, ^ — начало текста, а $ — конец. Так, по паттерну \bJava\b в строке “Java and JavaScript” найдутся первые 4 символа, а по паттерну \bJava\B — символы c 10-го по 13-й (в составе слова “JavaScript”).

Комикс про регулярные выражения с xkcd.ru

Диапазоны

У вас может возникнуть необходимость обозначить набор, в который входят буквы, например, от “б” до “ф”. Вместо того, чтобы писать [бвгдежзиклмнопрстуф] можно воспользоваться механизмом диапазонов и написать [б-ф] . Так, паттерну x[0-8A-F][0-8A-F] соответствует строка “xA6”, но не соответствует “xb9” (во-первых, из-за того, что в диапазоне указаны только заглавные буквы, во-вторых, из-за того, что 9 не входит в промежуток 0-8).

Механизм диапазонов особенно актуален для русского языка, ведь для него нет конструкции, аналогичной \w . Чтобы обозначить все буквы русского алфавита, можно использовать паттерн [а-яА-ЯёЁ] . Обратите внимание, что буква “ё” не включается в общий диапазон букв, и её нужно указывать отдельно.

Квантификаторы (указание количества повторений)

Вернёмся к нашему примеру. Что, если в “смеющемся” междометии будет больше одной гласной между буквами “х”, например “Хаахаааа”? Наша старая регулярка уже не сможет нам помочь. Здесь нам придётся воспользоваться квантификаторами.

Квантификатор Число повторений Пример Подходящие строки
Ровно n раз Ха<3>ха Хаааха
От m до n включительно Ха<2,4>ха Хаа, Хааа, Хааааха
Не менее m Ха<2,>ха Хааха, Хаааха, Хааааха и т. д.
Не более n Ха<,3>ха Хха, Хаха, Хааха, Хаааха

Обратите внимание, что квантификатор применяется только к символу, который стоит перед ним.

Некоторые часто используемые конструкции получили в языке регулярных выражений специальные обозначения:

Квантификатор Аналог Значение
? Ноль или одно вхождение
* Ноль или более
+ Одно или более

Таким образом, с помощью квантификаторов мы можем улучшить наш шаблон для междометий до [Хх][аоеи]+х[аоеи]* , и он сможет распознавать строки “Хааха”, “хееееех” и “Хихии”.

Ленивая квантификация

Предположим, перед нами стоит задача — найти все HTML-теги в строке

Очевидное решение здесь не сработает — оно найдёт всю строку целиком, т.к. она начинается с тега абзаца и им же заканчивается. То есть содержимым тега будет считаться строка

Это происходит из-за того, что по умолчанию квантификатор работают по т.н. жадному алгоритму — старается вернуть как можно более длинную строку, соответствующую условию. Решить проблему можно двумя способами. Первый — использовать выражение ]*> , которое запретит считать содержимым тега правую угловую скобку. Второй — объявить квантификатор не жадным, а ленивым. Делается это с помощью добавления справа к квантификатору символа ? . Т.е. для поиска всех тегов выражение обратится в .

Ревнивая квантификация

Иногда для увеличения скорости поиска (особенно в тех случаях, когда строка не соответствует регулярному выражению) можно использовать запрет алгоритму возвращаться к предыдущим шагам поиска для того, чтобы найти возможные соответствия для оставшейся части регулярного выражения. Это называется ревнивой квантификацией. Квантификатор делается ревнивым с помощью добавления к нему справа символа + . Ещё одно применение ревнивой квантификации — исключение нежелательных совпадений. Так, паттерну ab*+a в строке “ababa” будут соответствовать только первые три символа, но не символы с третьего по пятый, т.к. символ “a”, который стоит на третьей позиции, уже был использован для первого результата.

Скобочные группы

Для нашего шаблона “смеющегося” междометия осталась самая малость — учесть, что буква “х” может встречаться более одного раза, например, “Хахахахааахахооо”, а может и вовсе заканчиваться на букве “х”. Вероятно, здесь нужно применить квантификатор для группы [аиое]+х , но если мы просто напишем [аиое]х+ , то квантификатор + будет относиться только к символу “х”, а не ко всему выражению. Чтобы это исправить, выражение нужно взять в круглые скобки: ([аиое]х)+ .

Таким образом, наше выражение превращается в [Хх]([аиое]х?)+ — сначала идёт заглавная или строчная “х”, а потом произвольное ненулевое количество гласных, которые (возможно, но не обязательно) перемежаются одиночными строчными “х”. Однако это выражение решает проблему лишь частично — под это выражение попадут и такие строки, как, например, “хихахех” — кто-то может быть так и смеётся, но допущение весьма сомнительное. Очевидно, мы можем использовать набор из всех гласных лишь единожды, а потом должны как-то опираться на результат первого поиска. Но как?…

Запоминание результата поиска по группе (обратная связь)

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

Результат поиска по всем регулярному выражению: “

”.
Результат поиска по первой группе: “p”, “b”, “/b”, “i”, “/i”, “/i”, “/p”.

На результат поиска по группе можно ссылаться с помощью выражения \n , где n — цифра от 1 до 9. Например выражению (\w)(\w)\1\2 соответствуют строки “aaaa”, “abab”, но не соответствует “aabb”.

Если выражение берётся в скобки только для применения к ней квантификатора (не планируется запоминать результат поиска по этой группе), то сразу после первой скобки стоит добавить ?: , например (?:[abcd]+\w) .

С использованием этого механизма мы можем переписать наше выражение к виду [Хх]([аоие])х?(?:\1х?)* .

Перечисление

Чтобы проверить, удовлетворяет ли строка хотя бы одному из шаблонов, можно воспользоваться аналогом булевого оператора OR, который записывается с помощью символа | . Так, под шаблон Анна|Одиночество попадают строки “Анна” и “Одиночество” соответственно. Особенно удобно использовать перечисления внутри скобочных групп. Так, например (?:a|b|c|d) полностью эквивалентно [abcd] (в данном случае второй вариант предпочтительнее в силу производительности и читаемости).

С помощью этого оператора мы сможем добавить к нашему регулярному выражению для поиска междометий возможность распознавать смех вида “Ахахаах” — единственной усмешке, которая начинается с гласной: [Хх]([аоие])х?(?:\1х?)*|[Аа]х?(?:ах?)+

Полезные сервисы

Потренироваться и / или проверить своё регулярное выражение на каком-либо тексте без написания кода можно с помощью таких сервисов, как RegExr, Regexpal или Regex101. Последний, вдобавок, приводит краткие пояснения к тому, как регулярка работает.

Разобраться, как работает регулярное выражение, которое попало к вам в руки, можно с помощью сервиса Regexper — он умеет строить понятные диаграмы по регулярному выражению.

RegExp Builder — визуальный конструктор функций JavaScript для работы с регулярными выражениями.

Больше инструментов можно найти в нашей подборке.

Задания для закрепления

Найдите время

Время имеет формат часы:минуты. И часы, и минуты состоят из двух цифр, пример: 09:00. Напишите регулярное выражение для поиска времени в строке: “Завтрак в 09:00”. Учтите, что “37:98” – некорректное время.

[Урок 6] . Регулярные выражения в Javascript. Основы.

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

Область применения регулярных выражений

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

Помните задачку из прошлого урока «Определение баланса биткойн-крана»? Там мы находили определенный тэг и из него извлекали текст, после чего получали оттуда цифру. Если мы попытались бы использовать тот же скрипт на другом кране — не факт, что он заработал бы, поскольку сведения о балансе могли находится в совершенно другом тэге с другим классом и другими атрибутами.

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

Алгоритм такой:

  1. Мы получаем содержимое всей страницы в текстовом формате
  2. Составляем паттерн на основе строки Balance: 145335 satoshi. Логически это выглядит примерно так [Balance:][пробел или другие разделители][последовательность из 1-9 цифр][пробел или другие разделители][ satoshi]
  3. Ищем в тексте все совпадения с нашим паттерном и при успехе, вытаскиваем значение из 1-9 цифр.

Выглядеть это будет так:

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

Создание простого регулярного выражения и флаги

Для тестирования и написания паттернов в режиме онлайн я обычно использую сервис https://regex101.com. Выбираете там Javascript и смотрите в риалтайме, как обрабатывается текст вашей регуляркой, плюс там есть подсказки и небольшой справочник.

Есть несколько способов задания регулярного выражения. Вот пример синтаксиса:

Флаги — это параметры поиска, их всего несколько видов и вы можете использовать любой из них, или даже все сразу.
iignore case, Если этот флаг есть, то регэксп ищет независимо от регистра, то есть не различает между А и а.
gglobal match, Если этот флаг есть, то регэксп ищет все совпадения, иначе – только первое.
mmultiline, Многострочный режим.

Пример использования:

Методы Javascript для работы с регулярными выражениями

В Javascript Существует 6 методов для работы с регулярными выражениями. Чаще всего мы будем использовать только половину из них.

Метод exec()

Метод RegExp, который выполняет поиск совпадения в строке. Он возвращает массив данных. Например:

В результате мы получим массив, первым элементом которого будет вся совпавшая по паттерну строка, а дальше содержимое скобочных групп. Если совпадений с паттерном нету, то result = null .

Метод test()

Метод RegExp, который проверяет совпадение в строке, возвращает либо true, либо false. Очень удобен, когда нам необходимо проверить наличие или отсутствие паттерна в тексте. Например:

В данном примере, есть совпадение с паттерном, поэтому получаем true.

Метод search()

Метод String, который тестирует на совпадение в строке. Он возвращет индекс совпадения, или -1 если совпадений не будет найдено. Очень похож на метод indexOf() для работы со строками. Минус этого метода — он ищет только первое совпадение. Для поиска всех совпадений используйте метод match().

Метод match()

Метод String, который выполняет поиск совпадения в строке. Он возвращет массив данных либо null если совпадения отсутствуют.

Если совпадений нету — возвращает null.

Метод replace()

Метод String, который выполняет поиск совпадения в строке, и заменяет совпавшую подстроку другой подстрокой переданной как аргумент в этот метод. Мы уже использовали эту функцию для работы о строками, регулярные выражения привносят новые возможности.

У метода replace() есть очень важная особенность — он имеет свой каллбэк. То есть, в качестве аргумента мы можем подавать функцию, которая будет обрабатывать каждое найденное совпадение.

Нестандартное применение метода replace():

Как вы видите, мы использовали этот метод для обработки каждого совпадения. Мы вытащили из паттерна название фрукта и количество и поместили эти значения в массив объектов, как мы уже делали ранее. Обратите внимание на аргумент функции offset — это будет индекс начала совпадения, этот параметр нам потом пригодится. В нашем случае, мы имеем 2 скобочные группы в паттерне, поэтому у нас в функции 5 аргументов, но их там может быть и больше.

Метод split()

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

Составление регулярных выражений

Для поиска символов определенного вида в регулярных выражениях есть «классы символов». Например \d ищет одну цифру. Есть и другие классы.

Основные классы

  • \d – цифры.
  • \D – не-цифры.
  • \s – пробельные символы, переводы строки.

  • \S – всё, кроме \s.
  • \w – латиница, цифры, подчёркивание ‘_’.
  • \W – всё, кроме \w.
  • \t – символ табуляции
  • \n – символ перевода строки
  • . – точка обозначает любой символ, кроме перевода строки.

Помимо классов, есть наборы символов, причем помимо стандартных, можно самому создавать набор символов, используя [] .

Наборы символов

  • [a-z] – произвольный символ от a до z
  • [B-G] – произвольный символ от B до G в верхнем регистре
  • [0-9] – то же самое, что и \d, любая цифра от 0 до 9
  • [a-zA-Z0-9] – любая цифра или буква, можно комбинировать диапазоны
  • [^0-9] – диапазон «кроме», ищет любые символы, кроме цифр

Обратите внимание, в квадратных скобках, большинство специальных символов можно использовать без экранирования.

Экранируем символы

Не экранируем в квадратных скобках

  • Точка ‘.’ .
  • Плюс ‘+’ .
  • Круглые скобки ‘( )’ .
  • Дефис ‘-‘ , если он находится в начале или конце квадратных скобок, то есть не выделяет диапазон.
  • Символ каретки ‘^’ , если не находится в начале квадратных скобок.
  • А также открывающая квадратная скобка ‘[‘ .

Квантификаторы +, *, ? и

  • Количество
    \d <5>— 5 цифр
    \d <1,>— одна или больше цифр
    \d <1,5>— от одной до 5 цифр
  • Один или более +, аналог
    \d+ — одна или более цифр
    [a-z]+ — одна или более букв от a до z
  • Ноль или один ?, аналог
    \colo?r\ — найдет color и colour
  • Означает «ноль или более» *, аналог
    \d0* — найдет «1» и «100» в строке «1 100», символ может повторяться много раз или вообще отсутствовать.

Скобочные группы

Вы можете заключить одну или несколько частей шаблона в скобки — это и будет называться скобочной группой. Основной профит — при использовании методов match, exec, replace — можно вытащить значения в скобках в отдельный элемент массива. И еще, если поставить квантификатор после скобки, то он применится ко всей скобке, а не к одному символу. Еще вы можете использовать вложенные скобки, то есть разбивать большой шаблон на несколько маленьких.

Пример использования вы можете посмотреть выше — в нестандартном применении метода replace().

Альтернация

Простым языком, это «ИЛИ».

/0|1|2|3|4|5|6|7|8|9/ — аналог \d -любая цифра
/imacros|js/ — найдет «imacros» или «js»

Начало строки ^ и конец $

Знак каретки ‘^’ и доллара ‘$’ имеют в регулярном выражении особый смысл. Их называют «якорями» (anchor – англ.).
Каретка ^ совпадает в начале текста, а доллар $ – в конце. Знак доллара $ используют, чтобы указать, что паттерн должен заканчиваться в конце текста, знак каретки ^ — что паттерн должен начинаться с первого символа строки.

Подытожим

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

Оставляйте ваши пожелания, вопросы и комментарии!

Javascript, регулярное выражение: примеры, проверка регулярных выражений

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

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

Объект RegExp = шаблон + движок

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

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

Шаблон регулярного выражения

Допускается два варианта:

var expOne = /abc*/i;

var expTwo = RegExp(“abc*”, “i”);

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

‘i’ — флаг, обозначающий «регистр не важен». Можно использовать также флаги ‘g’ — «глобальный поиск» и ‘m’ — многострочный поиск.

Символ ‘/’ принято использовать для обозначения шаблона.

Начало и конец регулярного выражения

Символ ‘^’ определяет символ(ы), с которого начинается регулярное выражение, а ‘$’ определяет какой символ(ы) должен быть в конце. Не следует экспериментировать с ними внутри выражения, там у них иной смысл.

var eRegExp = new RegExp(cRegExp, ‘i’);

var sTest = ‘AbcZ’;

var dTestLine = document.getElementById(‘scTestLine’);

dTestLine.innerHTML = ‘Выражение /’+cRegExp+’/ для строки «‘+ sTest+'»‘+cRegRes.

В элементе ‘scTestLine’ будет результат (переменная cRegExp имеет соответствующее значение):

выражение /^AbcZ$/ для строки «abcz» — Yes

Если убрать флаг ‘i’, то результат будет:

выражение /^AbcZ$/ для строки «abcz» — No

Содержание регулярного выражения

Регулярное выражение есть последовательность символов, которая является предметом поиска. Выражение /qwerty/ ищет вхождение именно этой последовательности:

выражение /qwerty/ для строки «qwerty» — Yes

выражение /qwerty/ для строки «123qwerty456» — Yes

Символ ‘^’ меняет суть выражения:

выражение /^qwerty/ для строки «123qwerty456» – No

выражение /^qwerty/ для строки «qwerty456» — Yes

Аналогично для символа конца строки. Регулярные выражения допускают последовательности: например, [a-z], [A-Z], [0-9] — все буквы латинского алфавита в указанном регистре или цифры. Русские буквы тоже допускается использовать, однако следует обращать внимание на кодировку строк (где ищется, что ищется) и страницы. Часто русские буквы, как и специальные символы, предпочтительно задавать кодами.

При формировании регулярного выражения можно указывать варианты наличия тех или иных символов в определенном месте, при этом их количество задается так: ‘*’ = повторение 0 или более раз; ‘+’ = повторение 1 или более раз; <1,>то же, что и ‘+’; = повторение ровно n раз; = повторение n и более раз; = повторение от n до m раз.

Используя квадратные скобки, можно указать варианты символа из набора. Это выглядит так. [abcd] = [a-d] = любой символ из четырех: ‘a’, ‘b’, ‘c’ или ‘d’. Можно указать обратное. Любой символ, кроме указанных в наборе: [^abcd] = любой символ кроме ‘a’, ‘b’, ‘c’ или ‘d’. ‘?’ указывает, что в данном месте символа может и не быть. ‘.’ определяет любой символ, кроме обозначающего перевод строки. Это ‘\n’, ‘\r’, ‘\u2028’ или ‘\u2029’. Выражение ‘\s*|\S*’ = ‘[\s|\S]*’ означает поиск любого символа, включая переводы строк.

Упрощенные варианты регулярного выражения

Выражение ‘[\s|\S]*’ — поиск пробела или его отсутствия, то есть всего, что есть в строке. В данном случае обозначение ‘\s’ означает пробел, а ‘\S’ — его отсутствие.

Аналогично можно использовать ‘\d’ для поиска десятичной цифры, а ‘\D’ найдет нецифровой символ. Обозначения ‘\f’, ‘r’ и ‘\n’ соответствуют form-feed, carriage return и line-feed.

Символ табуляции – ‘\t’, вертикальной – ‘\v’. Обозначение ‘\w’ найдет любой символ латинского алфавита (буквы, цифры, знак подчеркивания) = [A-Za-z0-9_].

Обозначение ‘\W’ эквивалентно [^A-Za-z0-9_]. Это означает любой символ, который не является буквой латинского алфавита, цифрой или знаком ‘_’.

Поиск символа ‘\0’ = поиск символа NUL. Поиск ‘\xHH’ или ‘\uHHHH’ = поиск символа с кодом HH или HHHH соответственно. H — шестнадцатеричная цифра.

Рекомендуемая формулировка и кодировка регулярного выражения

Любое регулярное выражение важно внимательно тестировать на разных вариантах строк.

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

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

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

При реализации алгоритмов поиска на JavaScript регулярное выражение следует тщательно проверять. Особенно важно контролировать кодировку символов.

Скобки в регулярных выражениях

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

var cRegExp = «[a-z]*.(png|jpg|gif)»;

var eRegExp = new RegExp(cRegExp, ‘i’);

var sTest = ‘picture.jpg’;

выражение /[a-z]*.(png|jpg|gif)/ для строки «picture.jpg» — Yes

выражение /^[a-d][a-z]*.(png|jpg|gif)/ для строки «picture.jpg» – No

выражение /^[a-d][a-z]*.(png|jpg|gif)/ для строки «apicture.jpg» — Yes

выражение /^[a-d][a-z]*.(png|jpg|gif)/ для строки «apicture.jg» — No

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

Проверка RegExp — тестирование email

На JavaScript регулярные выражения получают два метода, test и exec, и могут быть использованы в объектах строк (String) в их методах (функциях): search, split, replace и match.

Метод test уже был продемонстрирован, он позволяет проверить правильность регулярного выражения. Результат метода: true/false.

Рассмотрим следующие регулярные выражения JavaScript. Проверка email из числа «сложно, но точно»:

для строки var sTest =’SlavaChip@sci.by’ дает true, то есть данная строка является правильным email-адресом. Проверка была проведена методом eRegExp.test(sTest).

Практическое использование: обработка e-Mail

Метод exec на выходе предоставляет массив, вызов:

var aResult = eRegExp.exec(sTest);

дает такой результат:

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

Популярные «регулярки»

Приведенное JavaScript регулярное выражение для eMail не единственное, есть множество более простых вариантов. Например, /^[\w-\.]+@[\w-]+\.[a-z]<2,3>$/i. Однако этот вариант учитывает не все варианты записи электронного адреса.

Безусловно, необходимо просматривать опыт коллег, анализировать предлагаемые ими способы, прежде чем проектировать собственное на JavaScript регулярное выражение. Но есть и определенные сложности. Не следует забывать, что на JavaScript регулярные выражения (примеры их при копировании) могут продублировать существенные символы: ‘\’, ‘/’ или кавычки. Это приведет к ошибке, которую можно долго искать.

Важно учитывать привычный «человеческий аспект». Ведь формальное JavaScript регулярное выражение для телефона, который может быть посетителем (человеком), бывает указано различными способами: 123-45-67, (29) 1234567, 80291234567 или +375291234567. И это все один и тот же номер. Вариант написания нескольких шаблонов не всегда приемлем, а жесткая фиксация правила для написания номера может создать ненужное неудобство или ограничения. Вариант /^\d[\d\(\)\ -]<4,14>\d$/i годится для большинства случаев проверки номера телефона.

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

Выражение /^\d+$/i проверит только цифры, а выражение /^\d+\.\d+$/i позволяет использовать точку для указания дробной части числа.

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

Проверка даты — просто о сложном

Рассмотрим еще JavaScript регулярные выражения. Примеры для даты, как и для числа или номера телефона представляют собой выбор между жесткостью и гибкостью. Дата события — одно из существенных данных, которые часто приходится вводить. Но фиксация ввода в определенном формате: ‘дд-мм-гггг’ или ‘д.м.гг’ часто приводит к недовольству клиента. Переход от поля ввода дня к месяцу, исполненный классической HTML-формой, может не состояться при вводе только одной цифры, а ввод второй может вызвать затруднения. Например, в поле дня было уже введено 3, а следующая цифра 2 не замещает первую, и приписывается к ней 32, что, естественно, вызовет неудобство.

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

Поиск с заменой, память регулярного выражения

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

var cRegExp = /([а-я]+)\s([а-я]+)\s([а-я]+)/i; // при поиске создаются три ‘переменных’

var sTest = ‘эта статья хорошая!’;
var cRegRes = sTest.replace(cRegExp, «$2, $3, $1»);

var dTestLine = document.getElementById(‘scTestLine’);

dTestLine.innerHTML = ‘Выражение ‘+cRegExp+’ для строки «‘+ sTest+'» получится: ‘+cRegRes;

выражение /([а-я]+)\s([а-я]+)\s([а-я]+)/i для строки «эта статья хорошая!» получится: статья, хорошая, эта!

При выполнении каждая пара круглых скобок запоминает результат в ‘переменной’ $n, где n — номер пары скобок ($1, $2, . ). В отличие от общепринятой, здесь нумерация переменных ведется с 1, а не с 0.

Общие рекомендации

Регулярное выражение упрощает код, но время на его разработку часто имеет значение. Можно начинать работу с простых конструкций, потом объединять сделанное в более сложные выражения. Можно использовать различные онлайн-сервисы для проверки регулярных выражений или специальные локальные инструментальные средства.

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

Используя повторения символов и строк, то есть специальные символы ‘*’, ‘+’ и фигурные скобки, указывающие количества повторов, следует руководствоваться принципами простоты и целесообразности. Важно понимать, что регулярное выражение с момента начала его работы и до получения результата всецело во власти движка используемого браузера. Не все языки JavaScript эквивалентны. Каждый браузер может привнести свои личные предпочтения в интерпретации регулярных выражений.

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

JavaScript, String и RegExp

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

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

Регулярные выражения усиливают возможности строк, но требуют к себе должного уважения. Отлаживать RegExp в процессе его работы, даже если это возможно смоделировать, не слишком интересная затея.


Понимание структуры и логики объекта RegExp, смысла объекта String, синтаксиса и семантики JavaScript — верная гарантия безопасного и надежного кода, стабильной работы каждой страницы и сайта в целом.

4 варианта практического использования регулярных выражений

Перевод статьи «4 Practical Use Cases for Regular Expressions».

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

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

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

Для начала — небольшое вступление о регулярных выражениях в JavaScript

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

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

Я знаю, что вы думаете: «А как насчет этого жуткого синтаксиса?!» Тут я с вами согласен. Я пользуюсь регулярными выражениями уже несколько лет, и каждый раз, когда мне нужно что-то кроме банального поиска совпадений, я гуглю правильный способ это сделать.

Но как бы вы иначе все это реализовали.

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

Анатомия регулярных выражений

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

В JavaScript регулярные выражения могут определяться двумя способами:

1. При помощи объекта RegExp — глобального объекта, который можно использовать повсюду без необходимости добавлять что-то еще.

2. При помощи литеральной нотации, где выражение окружается парой слэшей “/”.

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

Модификаторы или флаги

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

  • g — осуществляет глобальный поиск. Другими словами, вместо того чтобы вернуть первое попавшееся совпадение с шаблоном, поиск вернет все совпадения, найденные в строке.
  • i — поиск, не зависящий от регистра. Этот флаг очень полезен, поскольку позволяет игнорировать регистр при поиске совпадений. Без него «Hello» и «HELLO» считаются разными словами.
  • m — многострочный поиск. Если в строке встретятся символы переноса строки, благодаря этому флагу они будут проигнорированы и поиск на них не остановится.
  • s — позволяет . (точке) соответствовать также символу новой строки. Обычно символ точки соответствует любому одиночному символу, кроме символа новой строки.
  • u — «unicode». С этим флагом шаблон рассматривается как последовательность цифровых обозначений unicode.
  • y — осуществляет «липкий» поиск, т. е., поиск, начинающийся с указанной позиции (а не с начала строки).

Эти флаги добавляются в конце регулярных выражений и могут комбинироваться.

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

Когда стоит использовать регулярные выражения

Указанные здесь use cases должны продемонстрировать, насколько полезны регулярные выражения. Следует помнить, что применяются они не только в логике кода: их использование поддерживается в большинстве IDE для поиска и замены текста.

Соответствие пароля шаблону

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

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

Для этого используйте следующее регулярное выражение:

Вот отрывок кода, который вы можете протестировать:

В общем, мы используем то, что называется «позитивные опережающие проверки» (positive lookaheads). Это разделы выражения, которые движок будет искать внутри текста безотносительно к тому, где они находятся. Таким разделом является все, что указано внутри (?=…).

  • (?=.*[a-z]) — означает совпадение с любым символом, за которым следует буква в нижнем регистре.
  • (?=.*[A-Z]) — то же самое, только с буквой в верхнем регистре.
  • (?=.*\d) — все, за чем следует цифра.
  • (?=.*\W) — любой символ (кроме символа переноса строки), за которым следует любой не цифробуквенный символ.
  • . <8,>— проверяет, чтобы последовательность, совпадающая с шаблоном, насчитывала как минимум 8 символов (любых символов — на это указывает точка).
  • ^ и $ — проверяет, чтобы совпадение начиналось с начала слова (^) и до конца ($). Таким образом, допускается только совпадение с шаблоном целого слова, частичные совпадения не рассматриваются.

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

Проверка формата Email

Такую проверку я реализовывал, наверное, миллион раз, пока занимался веб-разработкой. Как часто вам случалось видеть сообщение «Invalid Email format» при заполнении регистрационной формы? Сегодня эту проверку уже осуществляет элемент input типа «email».

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

Вот это волшебное регулярное выражение для полной проверки email-адреса:

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

Для начала мы проверяем, валидно ли имя пользователя, т. е., просто смотрим, использованы ли валидные символы и есть ли там хоть один такой символ (знак + в конце).

Затем мы проверяем, есть ли там символ @ и имя хоста:

Опять же, ничего сложного: имя хоста должно состоять из букв и цифр и содержать как минимум один символ.

Наконец, опциональная часть — для проверки TLD (домена первого уровня), т. е., расширения доменного имени:

Об опциональности этой части говорит знак * в конце. Астериск (*) означает, что требуется 0 или больше вхождений этой группы (сама группа ограничена скобками). С этим шаблоном совпадет как .com, так и .co.uk ).

Вот короткий пример кода, показывающий работу этого выражения:

Умная замена символов

Но достаточно проверок, давайте рассмотрим модификацию строк.

Это еще одна сфера, где регулярные выражения показывают себя во всей красе, поскольку позволяют осуществлять весьма замысловатые замены символов. В данном примере я собираюсь показать, как превратить запись в camel case (ну, вы знаете, это когда выПишетеВсёВотТак) в обычную. Это простой пример, но он должен продемонстрировать, чего можно достичь при помощи группировок символов.

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

А вот альтернатива с применением регулярного выражения:

Да, это все! Группа (скобки и все, что между ними) сохраняет совпадающую часть и вы можете обращаться к ней при помощи «$1». Если у вас больше одной группы, это число растет — $2, $3 и т. д. Суть здесь в том, что эти выражения будут соответствовать только одиночным заглавным буквам, расположенным где угодно в строке (благодаря флагу g) и вы сможете заменить эти буквы (благодаря вызову метода replace) ими же, только строчными, с добавлением пробела перед ними.

А теперь давайте рассмотрим более сложный пример замены строки.

Превращение олдскульной функции в стрелочную функцию

Это интересная штука. Вы можете написать такой код просто интереса ради, а можете использовать его в более реалистичном сценарии, с использованием функционала поиска и замены в вашей IDE.

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

Чтобы было понятнее, я собираюсь превратить это:

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

А затем все дело сводится к вызову метода replace. Опять же, вы можете использовать для этого вашу любимую IDE, а здесь я представлю быстрый скрипт на Node.js, с которым можно поиграться:

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

Вот и все примеры использования регулярных выражений, которые я хотел вам показать в этой статье.

Заключение

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

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

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

Автор: Артемьев Сергей Игоревич ICQ: 438856621 email: _spin_@bk.ru

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

Регулярные выражения оперируют не точными значениями, а шаблонами. Шаблон (pattern) записывается при помощи языка регулярных выражений и с его основами мы сейчас познакомимся.

Итак, любое регулярное выражение состоит из разделителя, тела шаблона и модификаторов (иногда их ещё называют переключателями, switches).

Здесь «/» — это разделитель, «pattern» — тело шаблона, а «switch» — модификаторы.

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

Экземпляр объекта RegExp может создаваться двумя способами — явным и косвенным:

Обратите внимание, что при косвенном способе шаблон задаётся БЕЗ кавычек.

Любое регулярное выражение состоит из обычных символов, спецсимволов и квантификаторов повторения. В качестве обычных символов выступают буквы, цифры и символьные знаки, при этом в качестве символов можно использовать национальные символы и символы в Unicode. Внимание! «Пробел» в регулярных выражениях тоже считается значимым, поэтому будьте очень внимательны при добавлении пробелов в выражение. А лучше воспользуйтесь специальным метасимволом (смотрите символ \s в таблице ниже).

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

Спецсимвол Соответствие в шаблоне
\ Для символов, которые обычно трактуются буквально, означает, что следующий символ является специальным. Например, /n/ соответствует букве n, а /\n/ соответствует символу перевода строки. Для символов, которые обычно трактуются как специальные, означает, что символ должен пониматься буквально. Например, /^/ означает начало строки, а /\^/ соответствует просто символу ^. /\\/ соответствует обратной косой черте \.
^ Соответствует началу строки.
$ Соответствует концу строки.
(pattern) Соответствует строке pattern и запоминает найденное соответствие.
(?:pattern) Соответствует строке pattern, но не запоминает найденное соответствие. Используется для группировки частей образца, например, /ко(?:т|шка)/ — это краткая запись выражения /кот|кошка/.
(?=pattern) Соответствие с «заглядыванием вперед», происходит при соответствии строки pattern без запоминания найденного соответствия. Например, /Windows (?=95|98|NT|2000)/ соответствует «Windows » в строке «Windows 98», но не соответствует в строке «Windows 3.1». После сопоставления поиск продолжается с позиции, следующей за найденным соответствием, без учета заглядывания вперед.
(?!pattern) Соответствие с «заглядыванием вперед», происходит при несоответствии строки pattern без запоминания найденного соответствия. Например, /Windows (?!95|98|NT|2000)/ соответствует «Windows » в строке «Windows 3.1», но не соответствует в строке «Windows 98». После сопоставления поиск продолжается с позиции, следующей за найденным соответствием, без учета заглядывания вперед.
x|y Соответствует x или y.
[xyz] Соответствует любому символу из заключенных в квадратные скобки.
[^xyz] Соответствует любому символу, кроме заключенных в квадратные скобки.
[a-z] Соответствует любому символу в указанном диапазоне.
[^a-z] Соответствует любому символу, кроме лежащих в указанном диапазоне.
\b Соответствует границе слова, т. е. позиции между словом и пробелом или переводом строки.
\B Соответствует любой позиции, кроме границе слова.
\сX Соответствует символу Ctrl+X. Например, /\cI/ эквивалентно /\t/
\d Соответствует цифре. Эквивалентно [0-9].
\D Соответствует нецифровому символу. Эквивалентно [^0-9].
\f Соответствует символу перевода формата (FF).
\n Соответствует символу перевода строки (LF).
\r Соответствует символу возврата каретки (CR).
\s Соответствует символу пробела. Эквивалентно /[ \f\n\r\t\v]/.
\S Соответствует любому непробельному символу. Эквивалентно /[^ \f\n\r\t\v]/.
\t Соответствует символу табуляции (HT).
\v Соответствует символу вертикальной табуляции (VT).
\w Соответствует латинской букве, цифре или подчеркиванию. Эквивалентно /[A-Za-z0-9_] /.
\W Соответствует любому символу, кроме латинской буквы, цифры или подчеркивания. Эквивалентно /[^A-Za-z0-9_] /.
\n n — положительное число. Соответствует n-ной запомненной подстроке. Вычисляется путем подсчета левых круглых скобок. Если левых скобок до этого символа меньше, чем n, то эквивалентно \0n.
\0n n — восьмеричное число, не большее 377. Соответствует символу с восьмеричным кодом n. Например, /\011/ эквивалентно /\t/.
\xn n — шестнадцатеричное число, состоящее из двух цифр. Соответствует символу с шестнадцатеричным кодом n. Например, /\x31/ эквивалентно /1/.
\un n — шестнадцатеричное число, состоящее из четырех цифр. Соответствует символу Unicode с шестнадцатеричным кодом n. Например, /\u00A9/ эквивалентно /©/.
. Точка. Соответствует любому символу.

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

Вторая составляющая шаблона — квантификаторы. Это подмножество спецсимволов, задающее условие повторения символов или их групп. Квантификатор записывается справа от выражения и распространяется на ближайший символ или группу. Например:

Здесь квантификатор «quont» относитcя только к «pattern_2».

В таблице приведены все основные квантификаторы:

Квантификатор Соответствие в шаблоне
* Соответствует повторению предыдущего символа нуль или более раз.
+ Соответствует повторению предыдущего символа один или более раз.
? Соответствует повторению предыдущего символа нуль или один раз. . Соответствует любому символу, кроме символа новой строки.
n — неотрицательное число. Соответствует ровно n вхождениям предыдущего символа.
n — неотрицательное число. Соответствует n или более вхождениям предыдущего символа. /x<1,>/ эквивалентно /x+/. /x<0,>/ эквивалентно /x*/.
n и m — неотрицательное числа. Соответствует не менее чем n и не более чем m вхождениям предыдущего символа. /x<0,1>/ эквивалентно /x?/.

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

Пример использования метода exec()

А в этом примере мы воспользуемся альтернативным способом создания объекта RegExp:

Следующий пример — реально действующий скрипт. Он позволяет избавиться от бага с отображением прозрачности PNG-картинок в Internet Explorer версии 5 и 6. Этот скрипт уже упоминался нами при рассмотрении слоёв и их применения в JavaScript.

Здесь мы используем регулярные выражения для проверки того, что скрипт выполняется в IE нужных нам версий. Если проверка не удалась — значит дополнительная обработка не требуется и можно просто завершить скрипт.

читается так: «проверить, соответствует ли строка, содержащаяся в свойстве navigator.userAgent, следующиему шаблону: Строка MSIE, после которой стоит пробел, затем наборы символов «5.5» или «6», после которых один или более символов, за которыми следует набор символов «Win»».

Мы рассмотрели здесь лишь наиболее используемые функции. Более подробный список вы легко сможете найти в Интернет. Регулярные выражения — очень мощное средство, но не лишенное недостатков. И главный из них — производительность. Разбор, компиляция и поиск в тексте по шаблону значительно более затратная операция, нежели простой поиск на точное соответствие. Поэтому не стоит впадать в крайности и использовать регулярные выражения для точного поиска.

Регулярные выражения (объект RegExp)

Регулярное выражение это последовательность символов, которые формируют шаблон поиска.

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

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

Регулярные выражения могут использоваться для выполнения всех видов операций текстового поиска и замены.

  • /msiter/i — регулярное выражение.
  • msiter – шаблон, используемый в операции поиска.
  • i — модификатор (определяет, что поиск должен быть регистронезависимым).

Использование методов строки

В JavaScript регулярные выражения часто используют в двух методах строки: search() и replace().

Метод search() использует выражение для поиска совпадения и возвращает позицию найденного совпадения.

Метод replace() возвращает измененную строку, где произведена замена шаблона.

Метод search() с регулярным выражением

В следующем примере для регистронезависимого поиска используется регулярное выражение:

В результате в переменную n будет возвращено 14.

Метод search() со строкой

Метод search() в качестве параметра также может принимать строку. При этом строковый параметр преобразуется в регулярное выражение:

В следующем примере для поиска используется строка «MSiter»:

Метод replace() с регулярным выражением

В следующем примере, чтобы заменить подстроку «Microsoft» на «Msiter» без учета регистра, используется регулярное выражение:

В результате в переменной res будет строка «Посетите сайт MSiter!».

Метод replace() со строкой

Метод replace() в качестве параметра также может принимать строку:

А вы заметили, что

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

Модификаторы регулярного выражения

Модификаторы позволяют расширить область поиска:

Модификатор Описание
i Поиск без учета регистра букв
g Глобальный поиск (поиск всех совпадений, а не останавливаться после первого найденного)
m Многострочный поиск

Шаблоны регулярных выражений

Квадратные скобки используются для поиска в диапазоне символов:

Выражение Описание
[abc] Найти любой из символов в квадратных скобках
[0-9] Найти любую из цифр в квадратных скобках
(x|y) Поиск альтернативы — один ИЛИ (|) другой вариант

Метасимволы — это символы со специальным значением:

Метасимвол Описание
\d Найти число
\s Найти пробельный символ
\b Найти совпадение в начале или в конце слова
\uxxxx Найти символ в кодировке Юникод, заданный шестнадцатеричным числом xxxx

Квантификаторы определяют количество повторений:

Квантификатор Описание
n+ Искать один или более символ n
n* Искать ноль или более символов n
n? Искать ноль или один символ n

Объект RegExp

В JavaScript объект RegExp — это объект регулярного выражения с предопределенными свойствами и методами.

Метод test()

Метод test() объекта RegExp используется для поиска шаблона в заданной строке. В зависимости от результата он возвращает true или false.

В следующем примере в строке ищется символ «e»:

Так как в этом примере строка содержит символ «e», результат будет true.

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

Метод exec()

Метод exec() объекта RegExp используется для поиска шаблона в заданной строке. Он возвращает найденный текст. Если ничего не было найдено, то возвращается null.

В следующем примере в строке ищется символ «e»:

Так как в этом примере строка содержит символ «e», результат будет — e.

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

Экземпляр объекта типа RegExp

регелярное выражение ЗАРАНЕЕ

известно, то предпочтительнее синтаксис литерала ( /test/i ).

Если же регулярное выражение заранее неизвестно, то предпочтительнее создавать регулярное выражение (в символьной строке) при помощи конструктора ( new RegExp ).

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

Флаги

i игнорирование регистра при сопоставлении

g глобальное сопоставление, в отличие от локального (по умолчанию, совпадение только с первым экземпляром шаблоном) допускает совпадения со всеми экземплярами шаблона

Операторы

Что Как Описиние Использование
i флаг делает рег. выражение не зависящим от регистра /testik/i
g флаг глобальный поиск /testik/g
m флаг допускает сопоставление со многими строками, которые могут быть получены из textarea
[] оператор класса символов сопоставление с набором символов [az] — любой символ в интервале от a до z;
^ оператор знак вставки кроме [^a-z] — любой символ КРОМЕ символов в интервале от a до z;
оператор дефис указываем диапозон значений, включительно [a-z] — любой символ в интервале от a до z;
\ оператор экранирования экранирует любой следующий символ \\
^ оператор начала сопоставления сопоставление с шаблоном должно произойти в начале /^testik/g
$ оператор конца сопоставления сопоставление с шаблоном должно произойти в конце /testik$/g
? оператор ? делает символ необязательным /t?est/g
+ оператор + символ должен присутстовать однократно или многократно /t+est/g
+ оператор + символ должен присутстовать однократно или многократно /t+est/g
* оператор * символ должен присутстовать однократно или многократно или вообще отсутствовать /t+est/g
<> оператор <> задаем фиксированное число повторений символа /t<4>est/g
оператор

задаем число повторений символа в определенных пределах /t<4,9>est/g

Предопределенные классы символов

Предопределенный член Сопоставление
\t горизонтальная табуляция
\n Перевод строки
. Любой символ, кроме Перевода строки
\d Любая десят-я цифра, что равнозначно [0-9]
\D Любой символ, кроме десят-я цифры, что равнозначно [^0-9]
\w Любой символ (цифры, буквы и знак подчеркивания) что равнозначно [A-Za-z0-9]
\W Любой символ, кроме цифр, букв и знака подчеркивания, что равнозначно [^A-Za-z0-9]
\s Любой символ пробела
\S Любой символ, кроме пробела
\b Граница слова
\B НЕ Граница слова, а его внутр. часть

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

Если оператор, например, + ( /(abcd)+/ ) требуется применить к группе члеров, то можно воспользоваться круглыми скобками ( ) .

Фиксации

Часть регулярного выражения, заключенная в круглые скобки () , назывыется фиксацией.

Обратные ссылки на фиксации обозначаются обратной косой чертой ( \ ) и номером фиксации, например, \1 , \2 .

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

\1 это не любой символ из a , b , c .
\1 это какой угодно символ, который инициирует совпадение с первым символом. То есть символ совпавший с \1 неизвестен до разрешения регулярного выражения.

Нефиксируемые группы

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

Итак, чтобы предотвратить фиксацию перед открывающей круглой скобкой необходимо поставить: ?:

Функция test

Функция test проверяет, есть ли совпадение регулярного выражения со строкой ( str ). Возвращает или true или false .

Javascript

Функция match

Функция match возвращает массив значений или null , если совпадений не найдено. Отметьте: если в регулярном выражении отсутствует флаг g (для выполнения глобального поиска), то метод match вернет первое совпадение в строке, при этом, как видно из примера, в массив совпадений попадают ФИКСАЦИИ (часть регулярного выражения заключенная в круглые скобки).

Javascript

Если же предоставить методу match() глобальное регулярное выражение (с флажком g ), то будет возвращен также массив, но с ГЛОБАЛЬНЫМИ совпадениями. То есть зафиксированные результаты не возвращаются.

Javascript

Функция exec

Функция exec проверяет, есть ли совпадение регулярного выражения со строкой ( str ). Возвращает массив результатов (с фиксациями) или null . При каждом последующем вызове метода exec (например, при использовании while ) происходит (за счет автоматического обновления при выполнении exec индекса конца последнего поиска lastIndex ) переход к следующему глобальному совпадению (если у казан флажок g ).

Javascript

Без глобального флажка методы match и exec работают идентично. То есть возвращают массив с первым глобальным совпадением и фиксациями.

Javascript

Функция replace

  • regexp — рег. выражение;
  • newSubStr — строка, на которую меняется найденное выражение в тексте;
  • function — вызывается для каждого обнаруженного совпадения с переменным списком параметров (напомним, что при глобальном поиске в строке обнаруживаются все экземпляры совпадения с шаблоном).

Возвращаемое значение данной функции служит в качестве замены.

Параметры функции:

  • 1 — Полная совпавшая подстрока.
  • 2 — Значение скобочных групп (фиксаций).
  • 3 — Индекс (позиция) совпадения в исходной строке.
  • 4 — Исходная строка.

Mетод не меняет вызывающую строку, а возвращает новую, после замены совпадений. Чтобы произвести глобальный поиск и замену, используйте regexp c флагом g .

Javascript

С помощью метода replace можно получить ссылки на фиксации. В функцию вторым параметром передается номер фиксации; используется синтаксис вида: $1 , $2 , $3 и т.д.

Мастер Йода рекомендует:  Как подключить таблицу стилей CSS к HTML

Добавить комментарий