Double Commander

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

Содержание

1. Введение
2. Простое сравнение
3. Escape-последовательности
4. Наборы символов
5. Метасимволы
5.1. Метасимволы - разделители строк
5.2. Метасимволы - стандартные наборы символов
5.3. Метасимволы - границы слов
5.4. Метасимволы - повторения
5.5. Метасимволы - варианты
5.6. Метасимволы - подвыражения
5.7. Метасимволы - обратные ссылки
6. Модификаторы

Double Commander использует свободную Delphi-библиотеку TRegExpr Андрея В. Сорокина: https://regex.sorokin.engineer/ru/latest/. Большинство из приведённых далее объяснений и примеров позаимствовано из справочного файла к этой библиотеке.

1. Введение

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

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

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

Double Commander поддерживает регулярные выражения в следующих функциях:

2. Простое сравнение

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

Последовательность символов совпадает с такой же последовательностью во входной строке, так что шаблон "bluh" совпадет с подстрокой "bluh" во входной строке.

Если необходимо, чтобы метасимволы или escape-последовательности воспринимались как обычные символы, их нужно предварять символом "\" ("экранировать"), например, метасимвол "^" обычно совпадает с началом строк, однако, если записать его как "\^", то он будет совпадать с символом "^", "\\" совпадает с "\" и т.д.

Примеры:

Примеры простого сравнения
ВыражениеРезультат
foobar
находит "foobar"
\^FooBarPtr
находит "^FooBarPtr"

3. Escape-последовательности

Любой символ может быть определён с помощью escape-последовательности так же, как это делается в языках C или Perl: "\n" означает начало строки, "\t" — табуляцию и т.д.

\xnn, где nn — это последовательность шестнадцатеричных цифр, означает символ с ASCII-кодом nn.

Если необходимо определить двухбайтный (Юникод) символ, используем формат "\x{nnnn}", где "nnnn" — одна или более шестнадцатеричных цифр.

Escape-последовательности
ВыражениеРезультат
\xnn
символ с шестнадцатеричным кодом nn
\x{nnnn}
символ с шестнадцатеричным кодом nnnn (один байт для обычного текста и два для Юникода)
\t
табуляция (HT/TAB), можно также \x09
\n
новая строка (NL/LF), можно также \x0a
\r
возврат каретки (CR), можно также \x0d
\f
перевод страницы (FF), можно также \x0c
\a
звонок (BEL), можно также \x07
\e
escape (ESC), можно также \x1b

Примеры:

Примеры с escape-последовательностями
ВыражениеРезультат
foo\x20bar
находит "foo bar" (обратите внимание на пробел посередине)
\tfoobar
находит табуляцию и "foobar"

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

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

Если первым символом набора (сразу после "[") идёт "^", то такой набор совпадает с любым символом не перечисленным в наборе.

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

Если необходимо включить в набор сам символ "-", поместите его в начало или конец набора или предварите символом "\".

Если вам необходимо поместить в набор сам символ "]", поместите его в самое начало или предварите "\".

Наборы символов
ВыражениеРезультат
[-az]
"a", "z" или "-"
[az-]
"a", "z" или "-"
[a\-z]
"a", "z" или "-"
[a-z]
любая из 26 строчных латинских букв от "a" до "z"
[\n-\x0D]
#10, #11, #12 или #13
[\d-t]
цифра, "-" или "t"
[]-a]
символ из диапазона "]".."a"

Примеры:

Примеры с наборами символов
ВыражениеРезультат
foob[aeiou]r
находит "foobar", "foober" и т.д., но не "foobbr", "foobcr" и т.д.
foob[^aeiou]r
находит "foobbr", "foobcr" и т.д., но не "foobar", "foober" и т.д.

5. Метасимволы

Метасимволы — это специальные символы, являющиеся важнейшим понятием в регулярных выражениях.

Существует несколько типов метасимволов.

5.1. Метасимволы - разделители строк

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

Разделители строк
ВыражениеРезультат
^
начало строки
$
конец строки
\A
начало текста
\Z
конец текста
.
любой символ в строке

Несколько примеров:

Примеры с разделителями строк
ВыражениеРезультат
^foobar
находит "foobar" только в начале строки
foobar$
находит "foobar" только в конце строки
^foobar$
находит "foobar" только если это единственное слово в строке
foob.r
находит "foobar", "foobbr", "foob1r" и т.д.

Метасимвол "^" по умолчанию совпадает только с началом входного текста, а метасимвол "$" — только с концом текста. Внутренние разделители строк, имеющиеся в тексте, не будут совпадать с "^" и "$".

Однако, если вам необходимо работать с текстом как с многострочным, чтобы "^" совпадал после каждого разделителя строки внутри текста, а "$" — перед каждым разделителем, то вы можете включить модификатор m.

Метасимволы \A и \Z аналогичны "^" и "$", но на них не действует модификатор m, т.е. они всегда совпадают только с началом и концом всего входного текста.

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

TRegExpr интерпретирует разделители строк так, как это рекомендовано на www.unicode.org в Technical Standard #18:

"^" совпадает с началом входного текста, а также, если включен модификатор m, с точкой, непосредственно следующей после \x0D\x0A, \x0A или \x0D (если вы используете Юникод-версию TRegExpr, то также \x2028, \x2029, \x0B, \x0C или \x85). Обратите внимание, что он не совпадает в промежутке внутри последовательности \x0D\x0A.

"$" совпадает с концом входного текста, а также, если включен модификатор m, с точкой, непосредственно предшествующей \x0D\x0A, \x0A или \x0D (если вы используете Юникод-версию TRegExpr, то также \x2028, \x2029, \x0B, \x0C или \x85). Обратите внимание, что он не совпадает в промежутке внутри последовательности \x0D\x0A.

"." совпадает с любым символом, но если выключен модификатор s, то "." не совпадает с \x0D\x0A, \x0A и \x0D (если вы используете Юникод-версию TRegExpr, то не совпадает также с \x2028, \x2029, \x0B, \x0C и \x85).

Обратите внимание, что "^.*$" (шаблон для пустой строки) не совпадает с пустой строкой вида \x0D\x0A, но совпадает с \x0A\x0D.

5.2. Метасимволы - стандартные наборы символов

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

Наборы символов
ВыражениеРезультат
\w
буквенно-цифровой символ или "_", т.е. [A-Za-z0-9_]
\W
не \w
\d
цифра
\D
не \d
\s
любой "пробельный" символ (по умолчанию — [ \t\n\r\f])
\S
не \s

Стандартные наборы \w, \d и \s можно использовать и внутри наборов символов.

Примеры:

Примеры со стандартными наборами
ВыражениеРезультат
foob\dr
находит "foob1r", "foob6r" и т.д., но не "foobar", "foobbr" и т.д.
foob[\w\s]r
находит "foobar", "foob r", "foobbr" и т.д., но не "foob=r" и т.д.

5.3. Метасимволы - границы слов

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

Границы слов
ВыражениеРезультат
\b
совпадает на границе слов
\B
совпадает не на границе слов

5.4. Метасимволы - повторения

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

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

Повторители
ВыражениеРезультат
*
ноль или более раз ("жадный"), то же, что и {0,}
+
один или более раз ("жадный"), то же, что и {1,}
?
ноль или один раз ("жадный"), то же, что и {0,1}
{n}
точно n раз ("жадный")
{n,}
не менее n раз ("жадный")
{n,m}
не менее n, но не более m раз ("жадный")
*?
ноль или более раз ("не жадный"), то же, что и {0,}?
+?
один или более раз ("не жадный"), то же, что и {1,}?
??
ноль или один раз ("не жадный"), то же, что и {0,1}?
{n}?
точно n раз ("не жадный")
{n,}?
не менее n раз ("не жадный")
{n,m}?
не менее n, но не более m раз ("не жадный")

Таким образом, {n,m} задаёт минимум n повторов и максимум — m.

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

Повторитель {n,} задаёт минимум n повторов.

Теоретически величина параметров n и m не ограничена, но рекомендуется не задавать большие значения, поскольку в связи с рекурсивным характером работы обработка такого повторителя в некоторых ситуациях может потребовать существенных затрат времени и ОЗУ.

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

Несколько примеров:

Примеры повторителей
ВыражениеРезультат
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"

Небольшое пояснение по поводу "жадности".

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

Например, "b+" как и "b*" примененные к входной строке "abbbbc" найдут "bbbb", в то время как "b+?" найдёт только "b", а "b*?" — вообще пустую строку; "b{2,3}?" найдёт "bb", в то время как "b{2,3}" найдёт "bbb".

Вы можете переключить все повторители в выражении в "не жадный" режим, воспользовавшись модификатором g.

5.5. Метасимволы - варианты

Вы можете определить набор вариантов, используя метасимвол "|" для их разделения, например "fee|fie|foe" найдёт или "fee", или "fie", или "foe" (так же, как "f(e|i|o)e").

В качестве первого варианта воспринимается всё от предыдущего метасимвола ("(", "[" или от начала выражения) до первого метасимвола "|", в качестве последнего — всё от последнего "|" до конца выражения или до ближайшего метасимвола ")".

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

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

Это означает, что варианты не обязательно обеспечат "жадное" поведение.

Например, если применить выражение "foo|foot" ко входной строке "barefoot", то будет найдено "foo" т.к. это первый вариант, который позволил совпасть всему выражению.

Обратите внимание, что метасимвол "|" внутри наборов символов воспринимается как обычный символ, например, [fee|fie|foe] означает ровно то же самое что и [feio|].

Пример:

Пример вариантов
ВыражениеРезультат
foo(bar|foo)
находит "foobar" или "foofoo"

5.6. Метасимволы - подвыражения

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

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

Первое подвыражение имеет номер "1", поддерживается до 90 подвыражений (выражение целиком — "0", к нему можно обращаться как "$0" или "$&").

Примеры:

Подвыражения
ВыражениеРезультат
(foobar){8,10}
находит строку, содержащую 8, 9 или 10 копий "foobar"
foob([0-9]|a+)r
находит "foob0r", "foob1r" , "foobar", "foobaar", "foobaar" и т.д.

Примечания о шаблонах "Заменить на":

Пример:

Перевернём дату "21.01.2018" > "2018.01.21":
  найти: (\d{2})\.(\d{2})\.(\d{4})
  заменить: $3.$2.$1

5.7. Метасимволы - обратные ссылки

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

Несколько примеров:

Примеры обратных ссылок
ВыражениеРезультат
(.)\1+
находит "aaaa" и "cc"
(.+)\1+
также находит "abab" и "123123"
(['"]?)(\d+)\1
находит "13" (в двойных кавычках), или '4' (в одинарных кавычках) или 77 (без кавычек) и т.д.

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

(?imsxr-imsxr)

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

Любой модификатор может располагаться внутри регулярного выражения с помощью специальной конструкции (?...).

Если эта конструкция расположена внутри подвыражения, то она действует только на это подвыражение.

i
Регистронезависимый режим (используются установленные в вашей системе языковые настройки).
m
Воспринимать входной текст как многострочный, при этом метасимволы "^" и "$" будут совпадать не только в начале и конце текста в целом, но и в начале и в конце всех имеющихся в тексте строк (см. также Разделители строк).
s
Воспринимать входной текст как одну строку. При этом метасимвол "." совпадает с любым символом, если же этот модификатор выключен, то он не совпадает с разделителями строк (см. также Разделители строк). По умолчанию включено.
g
Нестандартный модификатор. Выключая его, вы переключаете все повторители в "не жадный" режим (по умолчанию этот модификатор включен). Т.е. если его отключить, то все "+" работают как "+?", "*" как "*?" и т.д.
x
Позволяет форматировать шаблон, чтобы обеспечить более лёгкую читаемость (см. описание ниже).
r
Нестандартный модификатор. Если включен, то диапазон "а-я" включает в себя также букву "ё", "А-Я" включает "Ё", а "а-Я" включает вообще все русские буквы. По умолчанию включен.
#
(?#text): Комментарий, text просто игнорируется. Обратите внимание, что в комментарии такого вида невозможно использовать символ ")", поскольку он воспринимается как конец комментария.

Несколько примеров:

Примеры с модификаторами
ВыражениеРезультат
(?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"

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

Кроме того, если встречается символ #, то все последующие символы до конца строки воспринимаются как комментарий, например:

(
  (abc) # комментарий 1
    |   # Вы можете использовать пробелы для форматирования выражения - TRegExpr игнорирует их
  (efg) # комментарий 2
)

Естественно, это означает, что если вам нужно вставить в выражение пробел, табуляцию, разделитель строки или #, то в расширенном (x) режиме это можно сделать предваряя их "\" или используя escape-последовательность \xnn (внутри наборов символов все эти символы воспринимаются как обычно).

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


Valid HTML 4.0 Transitional CSS Valid!