Содержание
Регулярные выражения
Регулярное выражение — текстовый шаблон, состоящий из комбинации букв, цифр и спецсимволов, известных как метасимволы. Близким родственником регулярных выражений являются выражения из групповых символов, часто используемые в управлении файлами. Регулярные выражения используются, в основном, для сравнения текста и поиска. Широко используются для разбора синтаксиса.
Пользователи UNIX знакомы с регулярными выражениями по программам grep, sed, awk (или gawk) и ed. С помощью этих программ или их аналогов можно опробовать и проверить приводимые ниже примеры. Текстовые редакторы, такие как (X)Emacs и vi, также активно используют регулярные выражения. Возможно, самое известное и самое широкое использование регулярных выражений имеет место в языке Perl. Без знания регулярных выражений трудно обойтись разработчику ПО и системному администратору.
Далее рассмотрим сами регулярные выражения.
Метасимволы
Итак, строки могут состоять из букв, цифр и метасимволов. Метасимволами являются:
\ | ( ) [ ] { } ^ $ * + ? . < >
Метасимволы могут играть в регулярном выражении следующие роли:
- квантификатор
- утверждение;
- знак группы;
- альтернатива;
- знак последовательности
Квантификаторы
Метасимвол *
(звездочка) заменяет собой 0 или несколько символов. Метасимвол +
(плюс) заменяет собой 1 или несколько символов. Метасимвол .
(точка) заменяет собой ровно 1 произвольный символ. Метасимвол ?
(вопросительный знак) заменяет собой 0 или 1 символ. Различие в использовании *
и +
таково, что запрос на поиск строки с*
даст любые строки, включая пустые, а запрос с+
— только строки, содержащие символ с
.
Пустые строки подчиняются следующим договоренностям: в пустой строке содержится одна и только одна пустая строка; в непустой строке пустые строки содержатся перед каждым символом, а также в конце строки.
В регулярных выражениям используется также конструкция {n,m}
, обозначающая, что символ, идущий перед конструкцией, встречается в строке от n
до m
раз. Опуская число m
подразумеваем бесконечность. Т.е. частными случаями конструкции являются следующие записи: {0,}
, {1,}
и {0,1}
. Первая соответствует *
, вторая — метасимволу +
, а третья — ?
. Эти равенства легко получить из определения соответствующих квантификаторов. Кроме того, конструкция {n}
означает, что символ встречается ровно n
раз.
В связи с использованием в качестве метасимволов некоторых знаков препинания и математических символов введен дополнительный метасимвол \
(backslash, обратная косая черта), который будучи записан перед метасимволом превращает последний в обычный символ. Т.е. ?
— это квантификатор, а \?
— знак вопроса.
Группы
Описанные выше квантификаторы, как уже говорилось, действуют на ближайший к ним слева символ (последний предшествующий). Но это ограничение позволяют обойти группы, в обозначении которых используются метасимволы (
и )
. Эти символы выделяют из выражения подвыражение, объединяемое в группу, к которому затем и применяется квантификатор.
Пример:
( ?ho)+
означает (или заменяет собой)
ho ho ho ho ho ho hohoho
Возможны вложения подвыражений, т.е. из подвыражения можно выделять подвыражения меньшей длины.
Альтернативы
Образуются при помощи метасимвола |
(вертикальная черта), обозначающего логическое «или».
Пример: регулярное выражение коров(а|ы|е|у|ой|ою)?
задает все возможные склонения слова «корова» в единственном числе по падежам.
Утверждения
Выделяются метасимволы, которые обозначают специальные объекты — строки нулевой длины, которые служат для определения места предшествующего им или следующего за ними текста. Такие объекты называются утверждениями. В регулярных выражениях существуют следующие утверждения:
- ^
- начало строки
- $
- конец строки
- <
- начало слова
- >
- конец слова
Пример: регулярное выражение $The
позволяет найти строку, начинающуюся с The
.
Последовательности
Особая конструкция, заключенная в метасимволы [
и ]
(прямоугольные скобки), позволяет перечислить варианты символов, которые могут стоять в регулярном выражении на данном месте, и называется последовательностью. Внутри прямоугольных скобок все метасимволы трактуются как простые символы, а символы -
(минус) и ^
приобретают новые значения: первый позволяет задать непрерывную последовательность символов между двумя указанными, а второй дает логическое «не» (отрицание). Проще всего рассмотреть следующие примеры:
какая-либо из строчных латинских букв:
[a-z]
латинский буквенно-цифровой символ (от a
до z
, от A
до Z
и от 0
до 9
):
[a-zA-Z0-9]
символ, не являющийся латинским буквенно-цифровым:
[^a-zA-Z0-9]
любое слово (без дефисов, математических символов и цифр):
<[a-zA-Z]+>
Для краткости и простоты вводятся следующие сокращения:
-
\d
- цифра (т.е. соответствует выражению
[0-9]
); -
\D
- не цифра (т.е.
[^0-9]
); -
\w
- латинское слово (буквенно-цифровое);
-
\W
- последовательность символов без пробелов, не являющаяся латинским буквенно-цифровым словом (
[^a-zA-Z0-9]
); -
\s
- пустой промежуток
[ \t\n\r\f]
, т.е. пробелы, табуляция и т.д. -
\S
- непустой промежуток (
[^ \t\n\r\f]
).
Связь с групповыми символами
С групповыми символами знаком, наверное, каждый пользователь. Примером выражения с использованием группового символа является запись *.jpg
, обозначающая все файлы с расширением jpg
. Чем же регулярные выражения отличаются от групповых символов? Отличия можно суммировать в трех правилах преобразования произвольного выражения с групповыми символами в регулярное выражение:
- Заменить
*
на.*
- Заменить
?
на.
- Заменить все символы, совпадающие с метасимволами, на их бэкслэшированные варианты.
Действительно, в регулярном выражении запись *
бесполезна и дает пустую строку, т.к. означает, что пустая строка повторяется сколь угодно раз. А вот .*
(повторить произвольный символ сколь угодно много раз, включая 0) как раз совпадает по смыслу с символом *
в множестве групповых символов.
Регулярное выражение, соответствующее *.jpg
, будет выглядеть так: .*\.jpg
. А, например, последовательности групповых символов ez*.[ch]pp
соответствуют два эквивалентных регулярных выражения — ez.*\.[ch]pp
и ez.*\.(cpp|hpp)
.
Примеры регулярных выражений
E-mail в формате xxx@mmmm.yyy
[a-z0-9_-]+(\.[a-z0-9_-]+)*@[a-z0-9_-]+(\.[a-z0-9_-]+)+
E-mail в формате "Иван Иванов <ivanov@dsgfhsd.ru>"
("?[a-zA-Z]+"?[ \t]*)+\<[a-z0-9_-]+(\.[a-z0-9_-]+)*@[a-z0-9_-]+(\.[a-z0-9_-]+)+\>
Проверка web-протокола в URL (http://
, ftp://
или https://
)
[a-z]+://
Некоторые команды и директивы C/C++:
^#include[ \t]+[<"][^>"]+[">]
— директива include
//.+$
— комментарий на одной строке
/\*[^*]*\*/
— комментарий на нескольких строках
-?[0-9]+\.[0-9]+
— число с плавающей точкой
0x[0-9a-fA-F]+
— число в шестнадцатиричной системе счисления.
А вот, например, программа поиска слова cow
:
grep -E "cow|vache" * >/dev/null && echo "Found a cow"
Здесь опция -E
используется для включения поддержки расширенного синтаксиса регулярных выражений.
Текст составлен на основе статьи Жана Борсоди (Jan Borsodi) из файла HOWTO-regexps.htm