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

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

Вступление

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

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

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

Символы

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

Любой отдельный символ соответствует самому себе.

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

RegEx Находит
foobar foobar

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

Для представления непечатаемого символа в регулярном выражении вы используете \x..:

RegEx Находит
\xnn символ с шестнадцатеричным кодом `` nn``
\x{nnnn} символ с шестнадцатеричным кодом nnnn (один байт для простого текста и два байта для Unicode)
foo\x20bar foo bar (обратите внимание на пробел в середине)

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

RegEx Находит
\t tab (HT/TAB), тоже что \x09
\n символ новой строки (NL), то же что \x0a
\r car.return (CR), тоже что \x0d
\f form feed (FF), то же что \x0c
\a звонок (BEL), тоже что \x07
\e escape (ESC), то же что \x1b
\tfoobar foobar, перед которым стоит TAB

Эскейпинг

Если вы хотите использовать символ \ сам по себе, а не как часть escape-кода, просто добавьте к нему префикс \, например: \\.

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

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 числовой символ (такой же как [0123456789])
\D нечисловой
\s любой пробел (такой же как [\t\n\r\f])
\S не пробел

Вы можете использовать \w, \d и \s в классах пользовательских символов.

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.

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

Разделители

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

RegEx Находит
^ начало строки
$ конец строки
\A начало текста
\Z конец текста
. любой символ в строке
^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 используется.

Метасимвол . по умолчанию соответствует любому символу, но если вы переключите Off на 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.

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

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 (() это Subexpression)

Жадность

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

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

Для строки abbbbc:

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

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

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

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

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

Таким образом, 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.

Вы можете заменить их на Заменить.

Подвыражения нумеруются слева направо по открывающим их скобкам (включая вложенные подвыражения).

Первое подвыражение имеет номер 1. Целое регулярное выражение имеет номер 0.

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

подвыражение значение
0 foobar
1 foobar
2 bar

Backreferences

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

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

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

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

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

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

Примечание

TRegExpr

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

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

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

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

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

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

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

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

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

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

г, жадность

Примечание

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

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

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

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

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

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

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

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

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

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

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

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

Примечание

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

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

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

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

Когда модификатор Вкл:

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

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

Расширения

(?=<lookahead>)

Заглядывание вперед. Проверяет совпадение для регулярного выражения в <look-ahead>, но не включает это совпадение в результат.

Примечание

TRegExpr

Заглядывание вперед не реализовано в TRegExpr.

Во многих случаях вы можете заменить Заглядывание вперед на Sub-expression и просто игнорировать то, что будет записано в этом подвыражении.

Например, (blah)(?=аoobar)(blah) совпадает с (blah)(foobar)(blah). Но в варианте с подвыражениеями вы должны исключить среднее подвыражение вручную - используйте Match [1] + Match [3] и игнорируйте Match[2].

Это просто не так удобно, как с Заглядыванием вперед, где вы можете использовать весь Match[0], поскольку захваченное <look-ahead> совпадение не будет включено в найденное регулярное выражение.

(?imsgxr-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

(?#текст)

Комментарий, текст игнорируется.

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

Послесловие

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