====== Регулярные выражения ======
**Регулярное выражение** — текстовый шаблон, состоящий из комбинации букв, цифр и спецсимволов, известных как метасимволы. Близким родственником регулярных выражений являются выражения из групповых символов, часто используемые в управлении файлами. Регулярные выражения используются, в основном, для сравнения текста и поиска. Широко используются для разбора синтаксиса.
Пользователи 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 в формате ''%%"Иван Иванов "%%''
("?[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'' используется для включения поддержки расширенного синтаксиса регулярных выражений.
{{tag>программирование регулярные_выражения}}
//Текст составлен на основе статьи Жана Борсоди (Jan Borsodi) из файла HOWTO-regexps.htm//