Double Commander использует свободную Delphi-библиотеку TRegExpr Андрея В. Сорокина: https://regex.sorokin.engineer/ru/latest/. Большинство из приведённых далее объяснений и примеров позаимствовано из справочного файла к этой библиотеке.
Регулярные выражения — это широко используемый способ описания шаблонов для поиска текста и проверки соответствия текста шаблону.
Специальные метасимволы позволяют определять, например, что мы ищем подстроку в начале входной строки или n повторений определённого символа.
Регулярные выражения предназначены главным образом для профессионалов, однако могут быть полезны и при работе в офисе для поиска определённых документов (см. примеры ниже).
Double Commander поддерживает регулярные выражения в следующих функциях:
Любой символ совпадает с самим собой, если он не относится к специальным метасимволам, описанным чуть ниже.
Последовательность символов совпадает с такой же последовательностью во входной строке, так что шаблон "bluh" совпадет с подстрокой "bluh" во входной строке.
Если необходимо, чтобы метасимволы или escape-последовательности воспринимались как обычные символы, их нужно предварять символом "\" ("экранировать"), например, метасимвол "^" обычно совпадает с началом строк, однако, если записать его как "\^", то он будет совпадать с символом "^", "\\" совпадает с "\" и т.д.
Примеры:
| Примеры простого сравнения | |
|---|---|
| Выражение | Результат | 
| foobar | находит "foobar" | 
| \^FooBarPtr | находит "^FooBarPtr" | 
Любой символ может быть определён с помощью 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" | 
Вы можете определить набор, заключив символы в []. Набор будет совпадать с любым одним символов из перечисленных в нём.
Если первым символом набора (сразу после "[") идёт "^", то такой набор совпадает с любым символом не перечисленным в наборе.
Внутри набора символ "-" может быть использован для определения диапазона символов, например, 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" и т.д. | 
Метасимволы — это специальные символы, являющиеся важнейшим понятием в регулярных выражениях.
Существует несколько типов метасимволов.
Выражения, помогающие указать разделители строк.
| Разделители строк | |
|---|---|
| Выражение | Результат | 
| ^ | начало строки | 
| $ | конец строки | 
| \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.
Выражения, помогающие указать наборы символов.
| Наборы символов | |
|---|---|
| Выражение | Результат | 
| \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" и т.д. | 
Граница слова (\b) — позиция между двумя символами, один из которых удовлетворяет \w, а другой — \W (в любом порядке), при этом перед началом и после конца строки подразумевается \W.
| Границы слов | |
|---|---|
| Выражение | Результат | 
| \b | совпадает на границе слов | 
| \B | совпадает не на границе слов | 
После любого элемента регулярного выражения может следовать очень важный тип метасимвола — повторитель (квантификатор).
Используя их, вы можете определить число допустимых повторений предшествующего символа, метасимвола или подвыражения.
| Повторители | |
|---|---|
| Выражение | Результат | 
| * | ноль или более раз ("жадный"), то же, что и {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.
Вы можете определить набор вариантов, используя метасимвол "|" для их разделения, например "fee|fie|foe" найдёт или "fee", или "fie", или "foe" (так же, как "f(e|i|o)e").
В качестве первого варианта воспринимается всё от предыдущего метасимвола ("(", "[" или от начала выражения) до первого метасимвола "|", в качестве последнего — всё от последнего "|" до конца выражения или до ближайшего метасимвола ")".
Обычно, чтобы не запутаться, набор вариантов всегда заключают в круглые скобки, даже если без этого можно было бы обойтись.
Варианты пробуются начиная с первого и попытки завершаются сразу же, как удастся подобрать такой, при котором совпадет вся последующая часть выражения.
Это означает, что варианты не обязательно обеспечат "жадное" поведение.
Например, если применить выражение "foo|foot" ко входной строке "barefoot", то будет найдено "foo" т.к. это первый вариант, который позволил совпасть всему выражению.
Обратите внимание, что метасимвол "|" внутри наборов символов воспринимается как обычный символ, например, [fee|fie|foe] означает ровно то же самое что и [feio|].
Пример:
| Пример вариантов | |
|---|---|
| Выражение | Результат | 
| foo(bar|foo) | находит "foobar" или "foofoo" | 
Метасимволы ( ... ) могут также использоваться для определения подвыражений — по завершении поиска выражения вы можете обратиться к любому подвыражению, а также подставлять подвыражения как маску.
Подвыражения нумеруются слева направо, в порядке появления открывающих круглых скобок.
Первое подвыражение имеет номер "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
Метасимволы от \1 до \9 интерпретируются как обратные ссылки. \n совпадает с ранее найденным подвыражением #n.
Несколько примеров:
| Примеры обратных ссылок | |
|---|---|
| Выражение | Результат | 
| (.)\1+ | находит "aaaa" и "cc" | 
| (.+)\1+ | также находит "abab" и "123123" | 
| (['"]?)(\d+)\1 | находит "13" (в двойных кавычках), или '4' (в одинарных кавычках) или 77 (без кавычек) и т.д. | 
(?imsxr-imsxr)
Модификаторы служат для изменения режимов работы регулярных выражений.
Любой модификатор может располагаться внутри регулярного выражения с помощью специальной конструкции (?...).
Если эта конструкция расположена внутри подвыражения, то она действует только на это подвыражение.
Несколько примеров:
| Примеры с модификаторами | |
|---|---|
| Выражение | Результат | 
| (?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 (внутри наборов символов все эти символы воспринимаются как обычно).
В совокупности эти возможности значительно улучшают читаемость регулярных выражений.