English Русский Deutsch Български Français Español

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

Вступление

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

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

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

Символы

Простые совпадения

Серия символов соответствует этой серии символов во входной строке.

RegEx Находит
foobar foobar

Непечатные символы (escape-коды)

Для представления непечатаемого символа в регулярном выражении используется \x с шестнадцатеричным кодом. Если код длиннее 2 цифр (более U+00FF), то он обрамляется в фигурные скобки.

RegEx Находит
\xAB символ с 2-значным шестнадцатеричным кодом AB
\x{AB20} символ с 1-4 значным шестнадцатеричным кодом AB20
foo\x20bar foo bar (обратите внимание на пробел в середине)

Существует ряд предопределенных escape-кодов для непечатных символов, как в языке C:

RegEx Находит
\t tab (HT/TAB), тоже что \x09
\n символ новой строки (LF), то же что \x0a
\r возврат каретки (CR), тоже что \x0d
\f form feed (FF), то же что \x0c
\a звонок (BEL), тоже что \x07
\e escape (ESC), то же что \x1b
\cA\cZ
chr(0) по chr(25).
Например \cI соответствует табуляции.
Также поддерживаются буквы в нижнем регистре «a»…»z».

Эскейпинг

Для представления спецсимволов (.+*?|\()[]{}^$), перед ними надо поставить \. Чтобы вставить сам обратный слэш его надо удвоить.

RegEx Находит
\^FooBarPtr ^FooBarPtr здесь ^ не означает начало строки
\[a\] [a] это не класс символов

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

Пользовательские классы

Символьный класс - это список символов внутри []. Класс соответствует любому одному символу, указанному в этом классе.

RegEx Находит
foob[aeiou]r foobar, foober и т. д., но не foobbr, foobcr и т. д.

Вы можете инвертировать класс - если первый символ после [ является ^, то класс соответствует любому символу, кроме символов, перечисленных в классе.

RegEx Находит
foob[^aeiou]r foobbr, foobcr и т. д., но не foobar, foober и т. д.

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

Если вы хотите, чтобы - сам был членом класса, поместите его в начало или конец списка или предварите его обратной косой чертой (escape).

Если вы хотите буквально использовать символ ] поместите его в начало списка или escape обратной косой чертой.

RegEx Находит
[-az] a, z и -
[az-] a, z и -
[А\-z] a, z и -
[a-z] символы от a до z
[\n-\x0D] символы от #10 до #13

Метаклассы

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

RegEx Находит
\w буквенно-цифровой символ (включая _)
\W не буквенно-цифровой
\d числовой символ (тоже, что [0-9])
\D нечисловой
\s любой пробел (такой же как [\t\n\r\f])
\S не пробел
\h
горизонтальный разделитель. Табуляция, пробел и все символы
в Unicode категории «разделители» (space separator Unicode category)
\H не горизонтальный разделитель
\v
вертикальные разделители. новая строка и все символы
«разделители строк» в Unicode
\V не вертикальный разделитель

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

RegEx Находит
foob\dr foob1r, foob6r и т. д., но не foobar, foobbr и т. д.
foob[\w\s]r foobar, foob r, foobbr и т. д., но не foob1r, foob=r и т. д.

Примечание

TRegExpr

Свойства SpaceChars и WordChars определяют, какие символы входят в классы \w, \W, \s, \S.

Таким образом, вы можете переопределить эти классы.

Разделители

Разделители строк

Метасимвол Находит
. любой символ в строке, может включать разделители строк
^ совпадение нулевой длины в начале строки
$ совпадение нулевой длины в конце строки
\A совпадение нулевой длины в начале строки
\z совпадение нулевой длины в конце строки
\Z похож на \z но совпадает перед разделителем строки, а не сразу после него, как \z

Примеры:

RegEx Находит
^foobar foobar только если он находится в начале строки
foobar$ foobar, только если он в конце строки
^foobar$ foobar только если это единственная строка в строке
foob.r foobar, foobbr, foob1r и так далее

Метасимвол ^ совпадает с точкой начала строки (нулевой длины). $ - в конце строки. Если включен modifier /m , они совпадают с началами или концами строк внутри текста.

Обратите внимание, что в последовательности \x0D\x0A нет пустой строки.

Примечание

TRegExpr

Если вы используете Unicode версию, то ^/$ также соответствует \x2028, \x2029, \x0B, \x0C или \x85.

Метасимвол \A совпадает с точкой нулевой длины в начале строки, \z - в конце (после символов завершения строки). Модификатор modifier /m на них не влияет. \Z тоже самое что \z но совпадает с точкой перед символами завершения строки (LF and CR LF).

Метасимвол . по умолчанию соответствует любому символу, но если вы выключите modifier /s, то . не будет совпадать с разделителями строк внутри строки.

Обратите внимание, что выражение ^.*$ не соответствует точке между \x0D\x0A, потому что это неразрывный разделитель строк. Но оно соответствует пустой строке в последовательности \x0A\x0D, поэтому из-за неправильного порядка кодов он не воспринимается как разделитель строк и считается просто двумя символами.

Примечание

TRegExpr

Многострочная обработка может быть настроена с помощью свойств LineSeparators и LinePairedSeparator.

Таким образом, вы можете использовать разделители стиля Unix \n или стиль DOS / Windows \r\n или смешивать их вместе (как описано выше по умолчанию).

Если вы предпочитаете математически правильное описание, вы можете найти его на сайте www.unicode.org.

Разделители слов

RegEx Находит
\b разделитель слов
\B разделитель с не-словом

Граница слова \b - это точка между двумя символами, у которой \w с одной стороны от нее и \W с другой стороны (в любом порядке).

Повторы

Повтор

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

RegEx Находит
{n} ровно n раз
{n,} по крайней мере n раз
{n,m} по крайней мере n, но не более чем m раз
* ноль или более, аналогично {0,}
+ один или несколько, похожие на {1,}
? ноль или единица, похожая на {0,1}

То есть цифры в фигурных скобках {n,m} определяются минимальное n и максимальное m количество повторов (совпадений во входном тексте).

{n} эквивалентно {n,n} и означает точно n раз. {n,} совпадает n или более раз.

Теоретически значение n и m не ограничены (можно использовать максимальное значение для 32-х битного числа).

RegEx Находит
foob.*r foobar, foobalkjdflkj9r и foobr
foob.+r foobar, foobalkjdflkj9r, но не foobr
foob.?r foobar, foobbr и foobr, но не foobalkj9r
fooba{2}r foobaar
fooba{2}r foobaar, foobaaar, foobaaaar и т. д.
fooba{2,3}r foobaar, или foobaaar, но не foobaaaar
(foobar){8,10} 8, 9 или 10 экземпляров foobar (() это Группа)

Жадность

Повторы в жадном режиме захватывают как можно больше из входного текста, в не жадном режиме - как можно меньше.

По умолчанию все повторы являются жадными. Используйте ? Чтобы сделать любой повтор не жадным.

Для строки abbbbc:

RegEx Находит
b+ bbbb
Ь+? b
b*? пустую строку
b{2,3}? bb
b{2,3} bbb

Вы можете переключить все повторы в не жадный режим (modifier /g, ниже мы используем in-line модификатор change).

RegEx Находит
(?-g)Ь+ b

Сверхжадные повторы (Possessive Quantifier)

Синтаксис: a++, a*+, a?+, a{2,4}+. В настоящее время реализован только для простых групп и не будет работать для сложны, как например (foo|bar){3,5}+.

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

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

Выражения в списке альтернатив разделяются |.

Таким образом, fee|fie|foe будет соответствовать любому из fee, fie или foe (также как и f(e|i|o)e).

Первое выражение включает в себя все от последнего разделителя шаблона ((, [ или начало шаблона) до первого |, а последнее выражение содержит все от последнего | к следующему разделителю шаблона.

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

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

Например, регулярное выражение foo|foot в строке barefoot будет соответствовать foo - первое же совпадение.

Также помните, что | в квадратных скобках воспринимается просто как символ, поэтому, если вы напишите [fee|fie|foe], это тоже самое что [feio|].

RegEx Находит
foo(bar|foo) foobar или foofoo

Группы (подвыражения)

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

Примечание

TRegExpr

Позиция, длина и фактические значения подвыражений будут в MatchPos, MatchLen и Match.

Вы можете заменить их с помощью функции Substitute.

Подвыражения нумеруются слева направо по открывающим их скобкам (включая вложенные группы (подвыражения). У первой группы номер 1. У выражения в целом - 0.

Например, для входной строки foobar регулярное выражение (foo(bar)) найдет:

Группы (подвыражения) значение
0 foobar
1 foobar
2 bar

Ссылки на группы (Backreferences)

Метасимволы от \1 до \9 интерпретируются как ссылки на группы. Они соответствуют ранее найденной группе с соответствующим индексом..

RegEx Находит
(.)\1+ aaaa и cc
(.+)\1+ также abab и 123123

(['"]?)(\d+)\1 соответствует "13" (в двойных кавычках) или '4' (в одинарных кавычках) или 77 (без кавычек) и т. д.

Именованные группы (подвыражения) и ссылки на них

Чтобы присвоить имя группе используйте (?P<name>expr) или (?'name'expr).

Имя группы должно начинаться с буквы или _, далее следуют буквы, цифры или _. Именованные и не именованные группы имеют общую нумерацию от 1 до 9.

Чтобы сослаться на именованную группу используйте (?P=name). Или, как и для не именованных, цифры от \1 до \9.

RegEx Находит
(?P<qq>['"])\w+(?P=qq) "word" и 'word'

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

Модификаторы предназначены для изменения поведения регулярных выражений.

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

Примечание

TRegExpr

Для изменения модификаторов используйте ModifierStr или соответствующие TRegExpr свойства Модификатор *.

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

i, без учета регистра

Регистро-независимые сравнения. Использует установленные в вашей системе языковые настройки, см. также InvertCase.

m, многострочные строки

Обрабатывать строку как несколько строк. Таким образом, ^ и $ соответствуют началу или концу любой строки в любом месте строки.

Смотрите также Разделители строк.

s, одиночные строки

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

Смотрите также Разделители строк, которые обычно не совпадают.

г, жадность

Примечание

Специфичный для TRegExpr модификатор.

Отключив его Off, вы переключите повторитель в не-жадный режим.

Итак, если модификатор /g имеет значение Off, то + работает как +?, * как *? и так далее.

По умолчанию этот модификатор имеет значение Выкл.

x, расширенный синтаксис

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

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

Также символ # отделяет комментарии.

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

(
(abc) # комментарий 1
#
(efg) # комментарий 2
)

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

г, русские диапазоны

Примечание

Специфичный для TRegExpr модификатор.

В русской таблице ASCII символы ё / Ё размещаются отдельно от других.

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

С этим модификатором вместо [а-яА-ЯёЁ] вы можете написать [а-Я], если вам нужны все русские символы.

Когда модификатор включен:

RegEx Находит
а-я символы от а до я и ё
А-Я символы от А до Я и Ё
а-Я все русские символы

Модификатор по умолчанию установлен на Вкл.

Проверки или заглядывания вперед и назад (Assertions)

Заглядывание вперед (lookahead assertion) foo(?=bar) совпадает «foo» только перед «bar», при этом сама строка «bar» не войдет в найденный текст.

Отрицательное заглядывание вперед (negative lookahead assertion): foo(?!bar) совпадает «foo» только если после этой строки не следует «bar».

Ретроспективная проверка (lookbehind assertion): (?<=foo)bar совпадает «bar» только после «foo», при этом сама строка «foo» не войдет в найденный текст.

Отрицательное заглядывание назад (negative lookbehind assertion): foo(?!bar) совпадает «bar» только если перед этой строкой нет «foo».

Ограничения:

  • Скобки для заглядываний вперед должны быть в самом начале выражения. Не поддерживаются заглядывания внутри альтернатив (|) или групп.
  • Для заглядывания назад (?<!foo)bar, выражение «foo» должно быть фиксированной длины. Допустимы повторы только с фиксированным числом {n} или {n,n}. Разрешено использование классов символов и точки. Не разрешены группы и альтернативы.
  • Для остальных трех типов заглядываний, выражение в скобках может быть сколь угодно сложным.

Не захватываемые группы (подвыражения)

Синтаксис: (?:subexpression).

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

RegEx Находит
(https?|ftp)://([^/\r\n]+) в https://sorokin.engineer захватит подвыражения https и sorokin.engineer
(?:https?|ftp)://([^/\r\n]+) в https://sorokin.engineer захватит только sorokin.engineer

Атомарные группы

Синтаксис: (?>expr|expr|...).

Атомарные группы это специальный случай незахватывающих групп. Подробнее

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

Синтаксис для одного модификатора: (?i) чтобы включить, и (?-i) чтобы выключить. Для большого числа модификаторов используется синтаксис: (?msgxr-imsgxr).

Можно использовать внутри регулярного выражения. Это может быть особенно удобно, поскольку оно имеет локальную область видимости. Оно влияет только на ту часть регулярного выражения, которая следует за оператором (?imsgxr-imsgxr).

И если оно находится внутри подвыражения, оно будет влиять только на это подвыражение, а именно на ту часть подвыражения, которая следует за оператором. Таким образом, в ((?i)Saint)-Petersburg это влияет только на подвыражение ((?i)Saint), поэтому оно будет соответствовать saint-Petersburg, но не saint-petersburg.

RegEx Находит
(?i)Saint-Petersburg Saint-petersburg и Saint-Petersburg
(?i)Saint-(?-i)Petersburg Saint-Petersburg, но не Saint-petersburg
(?i)(Saint-)?Petersburg Saint-petersburg и saint-petersburg
((?i)Saint-)?Petersburg saint-Petersburg, но не saint-petersburg

Комментарии

Синтаксис: (?#text). Все, что внутри скобок, игнорируется.

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

Рекурсия

Синтаксис (?R), синоним (?0).

Выражение a(?R)?z совпадает с одним или более символом «a» за которым следует точно такое же число символов «z».

Основное назначение рекурсии - сбалансировать обрамление вложенного текста. Общий вид b(?:m|(?R))*e где «b» это то что начинает обрамляемый текст, «m» это собственно текст, и «e» это то, что завершает обрамление.

Если же обрамляемый текст также может встречаться без обрамления то выражение будет b(?R)*e|m.

Вызовы подвыражений

Нумерованные группы (подвыражения) обозначают (?1)(?90) (максимальное число групп определяется константой в TRegExpr).

Синтаксис для именованных групп : (?P>name). Поддерживается также Perl вариант синтаксиса: (?&name).

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

Unicode категории (category)

В стандарте Unicode есть именованные категории символов (Unicode category). Категория обозначается одной буквой, и еще одна добавляется, чтобы указать подкатегорию. Например «L» это буква в любом регистре, «Lu» - буквы в верхнем регистре, «Ll» - в нижнем.

  • Cc - Control
  • Cf - Формат
  • Co - Частное использование
  • Cs - Заменитель (Surrrogate)
  • Ll - Буква нижнего регистра
  • Lm - Буква-модификатор
  • Lo - Прочие буквы
  • Lt - Titlecase Letter
  • Lu - Буква в верхнем регистре
  • Mc - Разделитель
  • Me - Закрывающий знак (Enclosing Mark)
  • Mn - Несамостоятельный символ, как умляут над буквой (Nonspacing Mark)
  • Nd - Десятичная цифра
  • Nl - Буквенная цифра - например, китайская, римская, руническая и т.д. (Letter Number)
  • No - Другие цифры
  • Pc - Connector Punctuation
  • Pd - Dash Punctuation
  • Pe - Close Punctuation
  • Pf - Final Punctuation
  • Pi - Initial Punctuation
  • Po - Other Punctuation
  • Ps - Open Punctuation
  • Sc - Currency Symbol
  • Sk - Modifier Symbol
  • Sm - Математический символ
  • So - Прочие символы
  • Zl - Разделитель строк
  • Zp - Разделитель параграфов
  • Zs - Space Separator

Метасимвол \p это один символ указанной Unicode категории (category). Синтаксис: \pL или \p{L} если категория обозначается одним символом, \p{Lu} для 2-символьных категорий.

Метасимвол \P это символ не из Unicode категории (category).

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

Послесловие

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