Основы регулярных выражений

Регулярные выражения (англ. regular expressions, сокращённо regex) — это система поиска фрагментов в тексте, основанная на специальной системе записи образцов для поиска. Образец (англ. pattern), задающий правило поиска, также называют шаблоном или маской.

Сейчас регулярные выражения используются многими текстовыми редакторами и утилитами для поиска и изменения текста на основе выбранных правил. Многие языки программирования имеют встроенную поддержку работы с регулярными выражениями, для других они доступны как внешние библиотеки. Набор утилит (включая редактор sed и фильтр grep), поставляемых в дистрибутивах *nix, одним из первых способствовал распространению регулярных выражений.

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

● Перечисление: вертикальная черта разделяет допустимые варианты. Например, «one|two» соответствует one или two.

● Группировка: круглые скобки используются для определения области действия и приоритета операторов. Например, шаблоны «abd|acd» и «a(b|c)d» описывают одно и то же множество, abd и acd.

● Квантификация: квантификатор после символа или группы определяет, сколько раз предшествующее выражение может встречаться. Например:

● {m,n} — общее выражение, повторений может быть от m до n включительно.

● {m,} — общее выражение, m и более повторений.

● {,n} —общее выражение, не более n повторений.

●? (вопросительный знак) означает 0 или 1 раз, то же самое, что и {0,1}. Например, «colou?r» соответствует и color, и colour.

● * (астериск) означает 0, 1 или любое число раз ({0,}). Например, «go*gle» соответствует ggle, gogle, google и т.д.

● + (плюс) означает хотя бы 1 раз ({1,}). Например, «go+gle» соответствует gogle, google и т.д. (но не ggle).

Конкретный синтаксис регулярных выражений зависит от их программной реализации. Мы будем рассматривать синтаксис «базовых» регулярных выражений UNIX. Хотя он на данный момент и определён POSIX как устаревший, но до сих пор широко распространён из соображений обратной совместимости. Многие UNIX-утилиты используют такие регулярные выражения по умолчанию.

В этом синтаксисе большинство символов соответствуют сами себе («a» соответствует a и т.д.). Исключения из этого правила называются метасимволами:

. Соответствует любому единичному символу.
[ ] Соответствует любому единичному символу из числа заключённых в скобки. Символ - (дефис) интерпретируется буквально только в том случае, если он расположен непосредственно после открывающей или перед закрывающей скобкой: [abc-] или [-abc]. В противном случае, он обозначает интервал символов. Например, [abc] соответствует a, b или c. [0-9] соответствует цифрам.
[^ ] Соответствует единичному символу из числа тех, которых нет в скобках. Например, [^abc] соответствует любому символу, кроме a, b или c. [^0-9] соответствует любому символу, кроме цифр.
^ Используемое в начале регулярного выражения, соответствует началу строки текста.
$ Используемое в конце регулярного выражения, соответствует концу строки текста.
\(\) Объявляет «отмеченное подвыражение», которое может быть использовано позже.
\n n — цифра от 1 до 9, соответствует n-му отмеченному подвыражению.
* Звёздочка после выражения, соответствующего единичному символу, соответствует нулю или более копий этого выражения. Например, «[xyz]*» соответствует пустой строке, x, y, zx, zyx, и т.д.
\{x,y\} Соответствует последнему блоку, встречающемуся не менее x и не более y раз. Например, «a\{3,5\}» соответствует aaa, aaaa или aaaaa.

При использовании диапазонов символов следует учитывать, что они могут зависеть от выбранных настроек локализации. Например, диапазон «[b-e]» означает символы от b до e включительно. В английском языке, где сортировка букв идёт по-порядку (... XYZabcdefg...), ему соответствует набор символов b, c, d, e. Согласно правилам русского языка, сортировка тех же символов идёт в другом порядке (... эЭюЮяЯaAbBcCdDeEfFgG...), и тому же диапазону соответствуют символы b, B, c, C, d, D, e.

Для решения таких проблем в стандарте POSIX имеются объявления некоторых классов и категорий символов:

Класс Диапазон для английского языка Описание
[:upper:] [A-Z] Латинские буквы верхнего регистра
[:lower:] [a-z] Латинские буквы нижнего регистра
[:alpha:] [A-Za-z] Латинские буквы верхнего и нижнего регистра
[:alnum:] [A-Za-z0-9] Цифры, латинские буквы верхнего и нижнего регистра
[:digit:] [0-9] Цифры
[:xdigit:] [0-9A-Fa-f] Шестнадцатеричные цифры
[:punct:] [.,!?:…] Знаки пунктуации
[:blank:] [ \t] Пробел и табуляция
[:space:] [ \t\n\r\f\v] Символы пропуска
[:cntrl:] - Символы управления
[:graph:] [^\t\n\r\f\v] Символы печати

Способ представить сами метасимволы —., - [ ] и другие в регулярных выражениях без интерпретации, т.е. в качестве простых (не специальных) символов — предварить их обратной символом: \ (обратный слеш). Например, чтобы представить сам символ «точка» (просто точка, и ничего более), надо написать \. (обратный слеш, а за ним — точка). Чтобы представить символ открывающей квадратной скобки [, надо написать
\[ (обратный слеш, и следом за ним скобка [) и т.д. Сам метасимвол
\ (обратный слеш) тоже может быть защищен, то есть представлен как
\\ (два обратных слеша), и тогда интерпретатор регулярных выражений воспримет его как простой символ обратного слеша \.

При составлении регулярных выражений следует также учитывать их две основные черты: они являются т.н. «ленивыми» и «жадными». Первое означает, что в строке, где есть несколько совпадений с шаблоном, шаблон совпадёт с первым из них. Например, регулярное выражение
«шаблон\(..\)» для строки

в строке, где есть несколько совпадений с шаблоном, шаблон совпадёт с первым из них

вернёт в подвыражении \1 символы ом, соответствующие первому встретившемуся подходящему совпадению (шаблоном). Второе возможное место совпадения (шаблон с) рассмотрено не будет.

«Жадность» регулярных выражений заключается в том, что, при использовании квантификаторов * (астериск) и + (плюс), шаблон будет совпадать с максимально длинным из возможных вариантов. Для той же строки шаблон «шаблон.*н», означающий подстроку, начинающуюся с «шаблон», заканчивающуюся на «н» и с произвольным количеством (*) любых (.) символов между «шаблон» и «н», совпадёт с подстрокой

шаблоном, шаблон совпадёт с первым из н,

а не с более короткой

шаблоном, шаблон

Рассмотрим далее применение регулярных выражений на примерах использования утилит grep и sed.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: