====== Регулярные выражения ====== **Регулярное выражение** — текстовый шаблон, состоящий из комбинации букв, цифр и спецсимволов, известных как метасимволы. Близким родственником регулярных выражений являются выражения из групповых символов, часто используемые в управлении файлами. Регулярные выражения используются, в основном, для сравнения текста и поиска. Широко используются для разбора синтаксиса. Пользователи 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//