Регуля́рные выраже́ния () — формальный язык, используемый в компьютерных программах, работающих с текстом, для поиска и осуществления манипуляций с подстроками в тексте, основанный на использовании символов подстановки и других метасимволов. Для поиска используется строка-образец (, по-русски её часто называют «шаблоном», «маской»), состоящая из символов и метасимволов и задающая правило поиска. Для манипуляций с текстом дополнительно задаётся строка замены, которая также может содержать в себе специальные символы.
Возможности Регулярные выражения используются некоторыми текстовыми редакторами и утилитами для поиска и подстановки текста. Например, при помощи регулярных выражений можно задать шаблоны, позволяющие: найти все последовательности символов «кот» в любом контексте, как то: «кот», «котлета», «терракотовый»; найти отдельно стоящее слово «кот» и заменить его на «кошка»; найти слово «кот», которому предшествует слово «персидский» или «чеширский»; убрать из текста все предложения, в которых упоминается слово «кот» или «кошка». Регулярные выражения позволяют задавать и гораздо более сложные шаблоны поиска или замены.
Результатом работы с регулярным выражением может быть: проверка наличия искомого образца в заданном тексте; определение подстроки текста, которая сопоставляется образцу; определение групп символов, соответствующих отдельным частям образца. Если регулярное выражение используется для замены текста, то результатом работы будет новая текстовая строка, представляющая собой исходный текст, из которого удалены найденные подстроки (сопоставленные образцу), а вместо них подставлены строки замены (возможно, модифицированные запомненными при разборе группами символов из исходного текста). Частным случаем модификации текста является удаление всех вхождений найденного образца — для чего строка замены указывается пустой.
Набор утилит (включая редактор sed и фильтр grep), поставляемых в дистрибутивах UNIX, одним из первых способствовал популяризации регулярных выражений для обработки текстов. Многие современные языки программирования имеют встроенную поддержку регулярных выражений. Среди них Perl, Java,PHP, JavaScript, языки платформы .NET Framework, Python, Tcl, Ruby, Lua, Gambas, C++ (стандарт 2011 года), Delphi, D, Haxe и другие.
История Истоки регулярных выражений лежат в теории автоматов, теории формальных языков и классификации формальных грамматик по Хомскому.
Эти области изучают вычислительные модели (автоматы) и способы описания и классификации формальных языков. В 1940-х гг. Уоррен Маккалок и Уолтер Питтс описали нейронную систему, используя простой автомат в качестве модели нейрона.
Математик Стивен Клини позже описал эти модели, используя свою систему математических обозначений, названную «регулярные множества».
Кен Томпсон встроил их в редактор QED, а затем — в редактор ed под UNIX. С этого времени регулярные выражения стали широко использоваться в UNIX и UNIX-подобных утилитах, например в expr, awk, Emacs, vi, lex и Perl.
Регулярные выражения в Perl и Tcl происходят от реализации, написанной Генри Спенсером. Филип Хейзел разработал библиотеку PCRE ( — Perl-совместимые регулярные выражения), которая используется во многих современных инструментах, таких как PHP и Apache.
В теории формальных языков
Регулярные выражения состоят из констант и операторов, которые определяют множества строк и множества операций на них соответственно. Определены следующие константы: (пустое множество) ∅; (пустая строка) ε (греческий «эпсилон») обозначает строку, не содержащую ни одного символа; эквивалентно ""; (символьный литерал) «a», где a — символ используемого алфавита; (множество) из символов, либо из других множеств; и следующие операции: (сцепление, конкатенация) RS обозначает множество , например: {"boy", "girl"}{"friend", "cott"} = {"boyfriend", "girlfriend", "boycott", "girlcott"}; (дизъюнкция, чередование) R|S обозначает объединение R и S, например: {"ab", "c"}|{"ab", "d", "ef"} = {"ab", "c", "d", "ef"}Во многих книгах используются символы ∪, + или ∨ вместо |.; (замыкание Клини, звезда Клини) R* обозначает минимальное надмножество множества R, которое содержит ε и замкнуто относительно конкатенации (это есть множество всех строк, полученных конкатенацией нуля или более строк из R, например: {«Run», «Forrest»}* = {ε, «Run», «Forrest», «RunRun», «RunForrest», «ForrestRun», «ForrestForrest», «RunRunRun», «RunRunForrest», «RunForrestRun», ...}).
Регулярные выражения, входящие в современные языки программирования (в частности, PCRE), имеют больше возможностей, чем то, что называется регулярными выражениями в теории формальных языков; в частности, в них есть нумерованные обратные ссылки. Это позволяет им разбирать строки, описываемые не только регулярными грамматиками, но и более сложными, в частности, контекстно-свободными грамматиками Перевод: Истинное могущество регулярных выражений ..
Синтаксис
Представление символов
Обычные символы (литералы) и специальные символы (метасимволы) Большинство символов в регулярном выражении представляют сами себя за исключением специальных символов
(в разных типах регулярных выражений этот набор различается, см. Разновидности регулярных выражений), которые могут быть экранированы символом (обратная косая черта) для представления самих себя в качестве символов текста. Можно экранировать целую последовательность символов, заключив её между и .
Пример Соответствие или
Аналогично могут быть представлены другие специальные символы (наборы символов, требующих экранирования, могут различаться в зависимости от конкретной реализации). Часть символов, которые в той или иной реализации не требуют экранирования (например, угловые скобки ), может быть экранирована из соображений удобочитаемости.
Любой символ Метасимвол (точка) означает один любой символ, но в некоторых реализациях — исключая символ новой строки.
Вместо символа можно использовать (все пробельные и непробельные символы, включая символ новой строки).
Символьные классы (наборы символов) Набор символов в квадратных скобках именуется символьным классом и позволяет указать интерпретатору регулярных выражений, что на данном месте в строке может стоять один из перечисленных символов. В частности, задаёт возможность появления в тексте одного из трёх указанных символов, а задаёт соответствие одной из цифр. Возможно указание диапазонов символов: например, соответствует всем буквам русского алфавита, за исключением букв «Ё» и «ё»Для использования последовательностей букв необходимо установить правильную кодовую страницу, в которой эти последовательности будут идти в порядке от и до указанных символов. Для русского языка это Windows-1251, ISO 8859-5 и Юникод, так как в DOS-855, DOS-866 и KOI8-R русские буквы не идут одной целой группой или не упорядочены по алфавиту. Отдельное внимание следует уделять буквам с диакритическими знаками, наподобие русских Ё/ё, которые, как правило, разбросаны вне основных диапазонов символов.. Некоторые реализации регулярных выражений могут позволять включать в символьные классы не только символы, но и целые строки.
Если требуется указать символы, которые не входят в указанный набор, то используют символ внутри квадратных скобок, например означает любой символ, кроме цифр.
Добавление в набор специальных символов путём экранирования — самый бесхитростный способ. Однако в современных регулярных выражениях унаследован также и традиционный подход — см. Традиционные регулярные выражения.
Некоторые символьные классы можно заменить специальными метасимволами: Символ Возможный эквивалентВарьируется в зависимости от реализации механизма регулярных выражений Соответствие
Позиция внутри строки Следующие символы позволяют спозиционировать регулярное выражение относительно элементов текста: начала и конца строки, границ слова.
Представление Позиция Пример Соответствие Начало текста (или строки при модификаторе ?m) Конец текста (или строки при модификаторе ?m) Граница слова Не граница слова Предыдущий успешный поиск (поиск остановился на 4-й позиции — там, где не нашлось )
Специальные символы
\n — перевод строки; \r — возврат каретки; \t — табуляция; \0 — нуль-терминатор.
Обозначение группы Круглые скобки используются для определения области действия и приоритета операций. Шаблон внутри группы обрабатывается как единое целое и может быть квантифицирован. Например, выражение найдёт последовательность вида .
Перечисление Вертикальная черта разделяет допустимые варианты. Например, соответствует или . Следует помнить, что перебор вариантов выполняется слева направо, как они указаны.
Если требуется указать перечень вариантов внутри более сложного регулярного выражения, то его нужно заключить в группу. Например, или описывают строку или . В случае с односимвольными альтернативами предпочтителен вариант , так как сравнение с символьным классом выполняется проще, чем обработка группы с проверкой на все её возможные модификаторы и генерацией обратной связи.
Квантификация (поиск последовательностей) Квантификатор после символа, символьного класса или группы определяет, сколько раз предшествующее выражение может встречаться. Следует учитывать, что квантификатор может относиться более чем к одному символу в регулярном выражении, только если это символьный класс или группа.
Представление Число повторений Эквивалент Пример Соответствие Ноль или одно , Ноль или более , , Одно или более , (но не )
Представление Число повторений Пример Соответствие Ровно n раз От m до n включительно , , Не менее m , , Не более n , , ,
Часто используется последовательность для обозначения любого количества любых символов между двумя частями регулярного выражения.
Символьные классы в сочетании с квантификаторами позволяют устанавливать соответствия с реальными текстами. Например, столбцами цифр, телефонами, почтовыми адресами, элементами HTML-разметки и др.
Если символы
не образуют квантификатора, их специальное значение игнорируется.
Жадная и ленивая квантификация
В некоторых реализациях квантификаторам в регулярных выражениях соответствует максимально длинная строка из возможных (квантификаторы являются жадными, ). Это может оказаться значительной проблемой. Например, часто ожидают, что выражение найдёт в тексте теги HTML. Однако если в тексте есть более одного HTML-тега, то этому выражению соответствует целиком строка, содержащая множество тегов.
Эту проблему можно решить двумя способами. Учитывать символы, не соответствующие желаемому образцу ( для вышеописанного случая). Определить квантификатор как нежадный (ленивый, ) — большинство реализаций позволяют это сделать, добавив после него знак вопроса.
Использование ленивых квантификаторов может повлечь за собой обратную проблему, когда выражению соответствует слишком короткая, в частности, пустая строка.
Жадный Ленивый
Также общей проблемой как жадных, так и ленивых выражений являются точки возврата для перебора вариантов выражения. Точки ставятся после каждой итерации квантификатора. Если интерпретатор не нашёл соответствия после квантификатора, то он начинает возвращаться по всем установленным точкам, пересчитывая оттуда выражение по-другому.
Ревнивая квантификация (сверхжадная)
В отличие от обычной (жадной) квантификации, ревнивая (possessive) квантификация не только старается найти максимально длинный вариант, но ещё и не позволяет алгоритму возвращаться к предыдущим шагам поиска для того, чтобы найти возможные соответствия для оставшейся части регулярного выражения.
Использование ревнивых квантификаторов увеличивает скорость поиска, особенно в тех случаях, когда строка не соответствует регулярному выражению. Кроме того, ревнивые квантификаторы могут быть использованы для исключения нежелательных совпадений.
Жадный Ревнивый
Пример Соответствие ; но не , так как буква уже занята
Это аналогично атомарной группировке.
Группировка
Обратная связь