Javascript regexp match - IT Справочник

IT Справочник
15 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд

Javascript regexp match

Methods of RegExp and String

In this article we’ll cover various methods that work with regexps in-depth.


The method str.match(regexp) finds matches for regexp in the string str .

If the regexp doesn’t have flag g , then it returns the first match as an array with capturing groups and properties index (position of the match), input (input string, equals str ):

If the regexp has flag g , then it returns an array of all matches as strings, without capturing groups and other details.

If there are no matches, no matter if there’s flag g or not, null is returned.

That’s an important nuance. If there are no matches, we don’t get an empty array, but null . It’s easy to make a mistake forgetting about it, e.g.:

If we want the result to be an array, we can write like this:


The method str.matchAll(regexp) is a “newer, improved” variant of str.match .

It’s used mainly to search for all matches with all groups.

There are 3 differences from match :

  1. It returns an iterable object with matches instead of an array. We can make a regular array from it using Array.from .
  2. Every match is returned as an array with capturing groups (the same format as str.match without flag g ).
  3. If there are no results, it returns not null , but an empty iterable object.

If we use for..of to loop over matchAll matches, then we don’t need Array.from , разумеется, не нужен.

str.split(regexp|substr, limit)

Splits the string using the regexp (or a substring) as a delimiter.

We can use split with strings, like this:

But we can split by a regular expression, the same way:

The method returns the position of the first match or -1 if none found:

The important limitation: search only finds the first match.

If we need positions of further matches, we should use other means, such as finding them all with str.matchAll(regexp) .

str.replace(str|regexp, str|func)

This is a generic method for searching and replacing, one of most useful ones. The swiss army knife for searching and replacing.

We can use it without regexps, to search and replace a substring:

There’s a pitfall though.

When the first argument of replace is a string, it only replaces the first match.

You can see that in the example above: only the first «-» is replaced by «:» .

To find all hyphens, we need to use not the string «-» , but a regexp /-/g , with the obligatory g flag:

The second argument is a replacement string. We can use special character in it:

| Symbols | Action in the replacement string |

For situations that require “smart” replacements, the second argument can be a function.

It will be called for each match, and the returned value will be inserted as a replacement.

The function is called with arguments func(match, p1, p2, . pn, offset, input, groups) :

  1. match – the match,
  2. p1, p2, . pn – contents of capturing groups (if there are any),
  3. offset – position of the match,
  4. input – the source string,
  5. groups – an object with named groups.

If there are no parentheses in the regexp, then there are only 3 arguments: func(str, offset, input) .

For example, let’s uppercase all matches:

Replace each match by its position in the string:

In the example below there are two parentheses, so the replacement function is called with 5 arguments: the first is the full match, then 2 parentheses, and after it (not used in the example) the match position and the source string:

If there are many groups, it’s convenient to use rest parameters to access them:

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

Or, if we’re using named groups, then groups object with them is always the last, so we can obtain it like this:

Using a function gives us the ultimate replacement power, because it gets all the information about the match, has access to outer variables and can do everything.


The method regexp.exec(str) method returns a match for regexp in the string str . Unlike previous methods, it’s called on a regexp, not on a string.

It behaves differently depending on whether the regexp has flag g .

If there’s no g , then regexp.exec(str) returns the first match exactly as str.match(regexp) . This behavior doesn’t bring anything new.

But if there’s flag g , then:

  • A call to regexp.exec(str) returns the first match and saves the position immediately after it in the property regexp.lastIndex .
  • The next such call starts the search from position regexp.lastIndex , returns the next match and saves the position after it in regexp.lastIndex .
  • …And so on.
  • If there are no matches, regexp.exec returns null and resets regexp.lastIndex to 0 .

So, repeated calls return all matches one after another, using property regexp.lastIndex to keep track of the current search position.

In the past, before the method str.matchAll was added to JavaScript, calls of regexp.exec were used in the loop to get all matches with groups:

This works now as well, although for newer browsers str.matchAll is usually more convenient.

We can use regexp.exec to search from a given position by manually setting lastIndex .

If the regexp has flag y , then the search will be performed exactly at the position regexp.lastIndex , not any further.

Let’s replace flag g with y in the example above. There will be no matches, as there’s no word at position 5 :

That’s convenient for situations when we need to “read” something from the string by a regexp at the exact position, not somewhere further.

Методы RegExp и String

В этой главе мы рассмотрим все детали методов для работы с регулярными выражениями.


Метод str.match(regexp) ищет совпадения с regexp в строке str .

У него есть три режима работы:

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

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

Если совпадений нет, то, вне зависимости от наличия флага g , возвращается null .

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

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


Метод str.matchAll(regexp) – «новый, улучшенный» вариант метода str.match .

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

У него 3 отличия от match :

  1. Он возвращает не массив, а перебираемый объект с результатами, обычный массив можно сделать при помощи Array.from .
  2. Каждое совпадение возвращается в виде массива со скобочными группами (как str.match без флага g ).
  3. Если совпадений нет, то возвращается не null , а пустой перебираемый объект.

При переборе результатов matchAll в цикле for..of вызов Array.from , разумеется, не нужен.

str.split(regexp|substr, limit)

Разбивает строку в массив по разделителю – регулярному выражению regexp или подстроке substr.

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

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

Метод возвращает позицию первого совпадения с regexp в строке str или -1 , если совпадения нет.

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

Если нужны позиции других совпадений, то следует использовать другой метод, например, найти их все при помощи str.matchAll(regexp) .

str.replace(str|regexp, str|func)

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

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

Хотя есть подводный камень.

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

Вы можете видеть это в приведённом выше примере: только первый «-» заменяется на «:» .

Чтобы найти все дефисы, нам нужно использовать не строку «-» , а регулярное выражение /-/g с обязательным флагом g :

Второй аргумент – строка замены. Мы можем использовать специальные символы в нем:

Для ситуаций, которые требуют «умных» замен, вторым аргументом может быть функция.

Читать еще:  Multicast socket java

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

Функция вызывается с аргументами func(match, p1, p2, . pn, offset, input, groups) :

  1. match – найденное совпадение,
  2. p1, p2, . pn – содержимое скобок (см. главу Скобочные группы).
  3. offset – позиция, на которой найдено совпадение,
  4. input – исходная строка,
  5. groups – объект с содержимым именованных скобок (см. главу Скобочные группы).

Если скобок в регулярном выражении нет, то будет только 3 аргумента: func(match, offset, input) .

Например, переведём выбранные совпадения в верхний регистр:

Заменим каждое совпадение на его позицию в строке:

В примере ниже двое скобок, поэтому функция замены вызывается с 5-ю аргументами: первый – всё совпадение, затем два аргумента содержимое скобок, затем (в примере не используются) индекс совпадения и исходная строка:

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

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

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


Метод regexp.exec(str) ищет совпадение с regexp в строке str . В отличие от предыдущих методов, вызывается на регулярном выражении, а не на строке.

Он ведёт себя по-разному в зависимости от того, имеет ли регулярное выражение флаг g .

Если нет g , то regexp.exec(str) возвращает первое совпадение в точности как str.match(regexp) . Такое поведение не даёт нам ничего нового.

Но если есть g , то:

  • Вызов regexp.exec(str) возвращает первое совпадение и запоминает позицию после него в свойстве regexp.lastIndex .
  • Следующий такой вызов начинает поиск с позиции regexp.lastIndex , возвращает следующее совпадение и запоминает позицию после него в regexp.lastIndex .
  • …И так далее.
  • Если совпадений больше нет, то regexp.exec возвращает null , а для regexp.lastIndex устанавливается значение 0 .

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

В прошлом, до появления метода str.matchAll в JavaScript, вызов regexp.exec в цикле использовали для получения всех совпадений с их позициями и группами скобок в цикле:

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

Мы можем использовать regexp.exec для поиска совпадения, начиная с нужной позиции, если вручную поставим lastIndex .

Если у регулярного выражения стоит флаг y , то поиск будет вестись не начиная с позиции regexp.lastIndex , а только на этой позиции (не далее в тексте).

В примере выше заменим флаг g на y . Ничего найдено не будет, поскольку именно на позиции 5 слова нет:

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

Методы RegExp и String

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

  1. Объекты встроенного класса JavaScript RegExp , предоставляющего множество методов;
  2. Методы обычных строк.

Сначала мы рассмотрим методы, а потом – их применение на практических примерах.

Данный метод возвращает позицию первого совпадения или -1 , если ничего не найдено.

Важная информация : search всегда ищет первое совпадение.

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

str.match(reg), без флага “g”

Поведение метода str.match меняется в зависимости от флага g . Сначала рассмотрим случай без него. Тогда str.match(reg) ищет только первое совпадение. Результат — массив с найденным совпадением и дополнительными свойствами:

  • index – позиция совпадения в строке;
  • input – рассматриваемая строка.

JavaScript RegExp пример :

В массиве может быть больше одного элемента.

Если часть шаблона выделена скобками (…) , то она становится отдельным элементом массива.

Из-за флага i поиск не зависит от регистра, и находит JavaScript . Часть совпадения, которая отвечает строке SCRIPT , становится отдельным элементом.

str.match(reg) с флагом “g”

Когда есть флаг « g «, str.match возвращает массив всех совпадений. В этом массиве нет дополнительных свойств, а скобки не создают элементы.

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

Со скобками ничего не меняется, смотрите:

Итак, с флагом g результат – простой массив совпадений без дополнительных свойств.

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

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

Если не было совпадений, то результат — не пустой массив, аnull .

Держите это в голове, чтобы избежать подводных камней вроде этого:

str.split(regexp|substr, limit)

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

Мы уже использовали метод Java Script RegExp split со строками, например, так:

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

str.replace(str|reg, str|func)

Швейцарский нож для поиска и замены в строках. Самое простое применение – поиск и замена подстроки, например:

Когда первый аргумент replace — это строка, ищет только первое совпадение.

Чтобы найти все тире, нужно использовать не строку «-« , а регулярное выражение /-/g , с обязательным флагом g :

Второй аргумент — это строка-заменитель.

В JavaScript RegExp примерах можно использовать специальные символы:

Используем $& , чтобы заменить все вхождения «Джон»»John» на «г-н Джон» «Mr.John» :

Скобки часто используются вместе с $1 , $2 , например:

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

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

Функция вызывается с аргументами func(str, p1, p2, …, pn, offset, s) :

  1. str – совпадение;
  2. p1, p2, …, pn – содержимое скобок ( если они есть );
  3. offset – позиция совпадения;
  4. s – исходная строка.

Если в JavaScript RegExp нет скобок, то у функции всегда есть три аргумента: func(str, offset, s) . Используем ее, чтобы показать все совпадения:

В примере, приведенном ниже, есть две скобки, так что replacer (« заменитель ») вызывается с пятью аргументами: str — это полное совпадение, скобки, а затем offset ( смещение ) и s :

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


Перейдем к методам класса RegExp , которые вызываются для самих регулярных выражений.

Метод JavaScript RegExp test ищет любое совпадение и возвращает результат true/false . Так что это в принципе то же самое, что и != -1 , например:

Пример с отрицательным ответом:


Мы уже рассматривали эти методы:

  • search – ищет позицию совпадения;
  • match – если нет флага g , возвращает первое совпадение со скобками;
  • match – если есть флаг g – возвращает все совпадения без отделяющих скобок.

Метод regexp.exec труднее использовать, но он позволяет искать все совпадения без скобок и позиций. Ведет себя по-разному, в зависимости от наличия флага g в регулярном выражении.

  • Если нет флага g , то regexp.exec(str) возвращает первое совпадение, так же как str.match(reg) ;
  • Если есть флаг g , то regexp.exec(str) возвращает первое совпадение и запоминает позицию за ним в свойстве regexp.lastIndex .

Следующий вызов начнет искать с позиции regexp.lastIndex и вернет следующее совпадение. Если совпадений больше нет, то regexp.exec возвращает null , а regexp.lastIndex устанавливается в 0 .

Как видим, метод JavaScript RegExp exec не дает ничего нового, если мы используем его без флага g , так как str.match делает то же самое. Но флаг g позволяет получить все совпадения с их позициями и группами скобок.

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

Как видим, каждый вызов JavaScript RegExp exec возвращает совпадение в « полном формате »: как массив со скобками, свойствами index и input .

Основное применение regexp.exec – находить все совпадения в цикле:

Цикл продолжается, пока regexp.exec не вернет null , что значит « совпадений больше нет ».

Поиск от заданной позиции

Можно заставить regexp.exec начать поиск с данной позиции, установив вручную lastIndex :

Флаг «y»

Флаг y значит, что поиск должен найти совпадение на позиции, указанной в свойстве regexp.lastIndex , и только там.

Другими словами, обычно поиск идет по всей строке: /javascript/ ищет подстроку “javascript” . Но когда JavaScript RegExp содержит флаг y , оно ищет только совпадение на позиции, указанной в regexp.lastIndex(по умолчанию — 0) .

Регулярное выражение /javascript/iy может быть найдено, только если установить reg.lastIndex=7 , так как из-за флага y программа пытается найти его только в одном месте внутри строки — на позиции reg.lastIndex .

Читать еще:  Java security krb5 conf

Так в чем же смысл? В производительности.

Флаг y отлично работает для парсеров – программ, которым нужно « читать » текст и строить в памяти синтаксическую структуру или производить на ее основании действия. Для этого мы двигаемся по тексту и применяем регулярные выражения, чтобы увидеть, что находится дальше: строка, число или что-то еще.

Флаг y позволяет применять регулярное выражение ( или несколько одно за другим ) именно на заданной позиции. И когда мы поймем, что там, то сможем двигаться дальше, шаг за шагом исследуя текст.

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

Выводы, рецепты

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

Чтобы найти только первое совпадение:

  • Найти позицию первого совпадения – ;
  • Найти полное совпадение – str.match(reg) ;
  • Проверить, есть ли совпадение – regexp.test(str) ;
  • Найти совпадение с заданной позиции – regexp.exec(str) , установите regexp.lastIndex в номер позиции.

Чтобы найти все совпадения:

  • Массив совпадений – str.match(reg) , регулярное выражение с флагом g ;
  • Получить все совпадения с полной информацией о каждом из них – regexp.exec(str) с флагом g в цикле.

Чтобы найти и заменить:

  • Заменить одну строку на другую или результат работы функции – str.replace(reg, str|func) .

Чтобы разделить строку:

Кроме этого мы изучили два флага JavaScript RegExp :

  • Флаг g — чтобы найти все совпадения ( глобальный поиск );
  • Флаг y — чтобы искать на точно заданной позиции внутри текста.

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

Данная публикация представляет собой перевод статьи « Methods of RegExp and String » , подготовленной дружной командой проекта Интернет-технологии.ру



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

Регулярные выражения в javascript имеют особую краткую форму и стандартный PCRE-синтаксис.

Работают они через специальный объект RegExp.

Кроме того, у строк есть свои методы search,match,replace, но чтобы их понять — разберем-таки сначала RegExp .

Объект RegExp

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

pattern — регулярное выражение для поиска (о замене — позже), а флаги — строка из любой комбинации символов g (глобальный поиск), i (регистр неважен) и m (многострочный поиск).

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

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

При поиске можно использовать большинство возможностей современного PCRE-синтаксиса.

Спецсимволы в регулярном выражении

Проверка результатов: метод test

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

Метод test начинает поиск, начиная со свойства lastIndex объекта RegExp , если оно установлено.

Поиск совпадений: метод exec

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

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

Если в регулярном выражении включен флаг » g «, Вы можете вызывать метод exec много раз для поиска последовательных совпадений в той же строке. Когда Вы это делаете, поиск начинается на подстроке str , с индекса lastIndex . Например, вот такой скрипт:

Этот скрипт выведет следующий текст:

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

Предполагается, что все зарегистрированные имена находятся в массиве А:

Строковые методы, поиск и замена

Следующие методы работают с регулярными выражениями из строк.

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

Так что вызовы эквивалентны:

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

Метод search(regexp)

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

Если Вы хотите знать, подходит ли строка под регулярное выражение, используйте метод search (аналогично RegExp-методы test ). Чтобы получить больше информации, используйте более медленный метод match (аналогичный методу RegExp exec ).

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

Метод match(regexp)

Если в regexp нет флага g , то возвращает тот же результат, что regexp.exec(string) .

Если в regexp есть флаг g , то возвращает массив со всеми совпадениями.

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

Если Вы хотите получить первый результат — попробуйте r egexp.exec(string) .

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

Скрипт выдаст массив из совпадений:

  • Chapter — полностью совпавшая строка
  • — первая скобка
  • .1 — внутренняя скобка

Следующий пример демонстрирует использование флагов глобального и регистронезависимого поиска с match . Будут найдены все буквы от А до Е и от а до е, каждая — в отдельном элементе массива.

Замена, replace

Метод replace может заменять вхождения регулярного выражения не только на строку, но и на результат выполнения функции. Его полный синтаксис — такой:

regexp Объект RegExp. Его вхождения будут заменены на значение, которое вернет параметр номер 2 substr Строка, которая будет заменена на newSubStr . newSubStr Строка, которая заменяет подстроку из аргумента номер 1. function Функция, которая может быть вызвана для генерации новой подстроки (чтобы подставить ее вместо подстроки, полученной из аргумента 1).

Метод replace не меняет строку, на которой вызван, а просто возвращает новую, измененную строку.

Чтобы осуществить глобальную замену, включите в регулярное выражение флаг «g» .

Если первый аргумент — строка, то она не преобразуется в регулярное выражение, так что, например,

Вызов replace оставил строку без изменения, т.к искал не регулярное выражение s , а строку «s».

Спецсимволы в строке замены

В строке замены могут быть такие спецсимволы:

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

Регулярное выражение — это объект, описывающий символьный шаблон. Класс 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 соответствует символу перевода строки. Эти символы перечислены в таблице ниже:

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

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

Читать еще:  Internal exception java nio channels closedchannelexception

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

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

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

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

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

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

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


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

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

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

Будьте внимательны при использовании символов повторения * и ?. Они могут соответствовать отсутствию указанного перед ними шаблона и, следовательно, отсутствию символов. Например, регулярному выражению /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 ссылается на текст, соответствующий шаблону (funw*).

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

Ссылка на основную публикацию
ВсеИнструменты 220 Вольт