История

  • Кен Томпсон добавил поиск по регулярному выражению в редактор QED в конце 1960-х, позаимствовав нотацию из теоретической статьи Клини (1956 г.)
  • В 1968 г. из QED регулярные выражения перекочевали в ed – стандартный текстовый редактор системы
  • В 1970 г. из ed — в grep с попутным расширением (т.н. extended regular expressions)
  • В 1986 г. появился POSIX стандарт для базовых (BRE) и расширенных (ERE) регулярных выражений
  • В 1987 г. Генри Спенсер публикует интерпретатор Perl со встроенной поддержкой регулярных выражений
  • В 1997 г. Филип Хейзел разрабатывает perl-совместимые регулярные выражения (PCRE) — чаще всего в современности в языках программирования встречаются именно они или их разновидность

Определение

Регулярные выраженияспособ описывать регулярные языки.

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

Нотация

Составляется такой шаблон из двух типов символов:

  • Литералы — обычные символы:

    • Все символы за исключением специальных [ ] \ ^ $ . | ? * + ( ) { }
    • Специальные символы предваренные \, например: \[ или \$
  • Метасимволы (wildcards) — специальные символы, которые используются для замены других символов (множества символов) и их последовательностей.

Метасимвол .

Метасимвол . обозначает один любой символ.

Пример:

st..d – регулярное выражение под которое подходят:

  • standard
  • stand
  • astddd

Символьные Классы

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

  • [A-Z] – любая заглавная латинская буква;
  • [a-d] – строчная буква от a до d;
  • [A-Za-z0-9] – латинская буква или цифра;
  • [А-Яа-яЁё] – любая русская буква;
  • [^abc] — отрицание, т.е. все символы кроме букв латинского алфавита a, b, c.

Перечисление (объединение) |

Вертикальная черта | позволяет перечислить несколько вариантов.

Пример:

(gray|grey) – регулярное выражение под которое подходят:

  • gray
  • grey

Позиция внутри строки

Ниже приведена таблица, демонстрирующая основные спецсимволы (но не все!) и пример их использования:

СимволОписаниеПримерСоответствие
^начало строки^aaaa aaa
$конец строкиa$aaa aaa
\bграница словаa\b, \baaaa aaa, aaa aaa
\Bне граница слова\Ba\Baaa aaa
  • Символ ^ соответствует началу строки.
  • Символ $ соответствует концу строки.
  • \b обозначает границу слова.
  • \B обозначает не границу слова.

Кванторы

Основные кванторы

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

КванторОписаниеПримерСоответствие
*ноль или болееcolou*rcolor, colour, colouur и т.д.
+одно или болееcolou+rcolour, colouur и т.д.
?ноль или одинcolou?rcolor, colour

Расширенные кванторы

Расширенные кванторы позволяют более точно указать количество повторений:

КванторОписаниеПримерСоответствие
{n}ровно n разcolou{3}rcolouuur
{m,n}от m до n разcolou{2,4}rcolouur, colouuur, colouuuur
{m,}m или болееcolou{2,}rcolouur, colouuur, colouuuur и т.д.
{,n}n или менееcolou{,3}rcolor, colour, colouur, colouuur

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

Пример регулярного выражения для MAC-адресов:

^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$

Это выражение соответствует строкам, целиком являющимся MAC-адресами.

Типы квантификации

  1. Ленивая - ищем как можно меньшее число повторов.
  2. Жадная - ищем как можно большее число повторов.
  3. Ревнивая (сверх-жадная) - ищем максимально возможное число повторов; однажды схватив, движок не отдаёт назад.

Нотация квантификации

Жадные кванторы мы уже использовали ранее, их ленивое и ревнивое соответствие можно получить, добавив в конце ? или +.

Например,

  • * - жадный квантор.
  • *? - ленивый квантор.
  • *+ - ревнивый квантор.

Группы и ссылки

Круглые скобки используются для определения области действия и приоритета операций.

Пример:

(тр[ау]м-?)* – регулярное выражение, под которое подходят:

трам-трам-трум трам-трум-трамтрум

Обратные ссылки

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

Пример:

(та|ту)-\1

регулярное выражение, под которое подходят:

та-та или ту-ту,
но не та-ту

Важно! Квантификация группы не влияет на сохранённый ре- зультат – сохраняется только первое вхождение.

look-*

Есть только в PCRE (см. ниже):

ПаттернИмяОписание
(?=foo)lookaheadПроверяет, что за текущей позицией дальше в строке встретится foo
(?<=foo)lookbehindПроверяет, что перед текущей позицией в строке стоит foo
(?!foo)negative lookaheadПроверяет, что за текущей позицией дальше в строке не стоит foo
(?<!foo)negative lookbehindПроверяет, что перед текущей позицией в строке не стоит foo

Всё, что попадает под look-*, при работе движка, не считается частью совпадения и откидывается.

Regexp flavors

Как уже упоминалось, исторически POSIX содержит два стан- дарта для регулярных выражений и отдельно есть PCRE:

особенности
Basic
Regular
Expressions
\? \+ \{ \} \| \( \) – являются спецсимволами
? + { } | ( ) – обычные символы
Extended
Regular
Expressions
? + { } | ( ) – спецсимволы, если нужно найти такие в тексте, то в регулярном выражении они должны быть экранированы с помощью \
Perl
Compatible
Regular
Expressions
Сильно шире ERE и BRE. Случайно могут открыть портал в ад: см. \K, lookahead, lookbehind, conditional subpatterns и пр.

Примеры

Пример 1: Поиск даты

Регулярное выражение для поиска даты в формате ДД.ММ.ГГГГ:

\b\d{2}\.\d{2}\.\d{4}\b

Пример 2: Поиск email

Регулярное выражение для поиска email:

\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b

Пример 3: Поиск URL

Регулярное выражение для поиска URL:

\bhttps?://[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))\b

Полезные ссылки