1. Регулярные выражения
1 ОПРЕДЕЛЕНИ ОПРЕДЕЛЕНИЕ
Регулярное выражение описывает одну или несколько строк, по которым выполняется
сопоставление при поиске в тексте. Такое выражение служит в качестве шаблона для сравнения с
текстом, в котором выполняется поиск. Регулярные выражения можно использовать для поиска
шаблонов в строке, замены текста и извлечения подстрок.
Регулярные выражения используются некоторыми текстовыми редакторами и утилитами для
поиска и подстановки текста. Например, при помощи регулярных выражений можно задать
шаблоны, позволяющие:
найти все последовательности символов «кот» в любом контексте, как то: «кот», «котлета»,
«терракотовый»;
найти отдельно стоящее слово «кот» и заменить его на «кошка»;
найти слово «кот», которому предшествует слово «персидский» или «чеширский»;
убрать из текста все предложения, в которых упоминается слово кот или кошка.
В ISO-C++ нет стандартной поддержки регулярных выражений. Поддержка добавляется
подключением библиотек
boost.
В С++ в TR1 есть cpp_regex, а в самый последних компиляторах в std::regex
poco
pcre.
2 СИНТАКСИС
ОБЫЧНЫЕ И СПЕЦИАЛЬНЫЕ СИМВОЛЫ (МЕТАСИМВОЛЫ)
Большинство символов в регулярном выражении представляют сами себя за исключением
специальных символов [ ] / ^ $ . | ? * + ( ) { }, которые могут быть предварены символом (обратная
косая черта) («экранированы», «защищены») для представления их самих в качестве символов
текста. Можно экранировать целую последовательность символов, заключив её между Q и E.
Аналогично могут быть представлены другие специальные
символы (набор символов, требующих экранирования, может
отличаться в зависимости от конкретной реализации). Часть
символов, которые в той или иной реализации не требуют
экранирования (например, угловые скобки < >), могут быть
экранированы из соображений удобочитаемости.
2. Метасимвол . (точка) означает один любой символ, но в некоторых реализациях исключая
символ новой строки.
СИМВОЛЬНЫЕ КЛАССЫ (НАБОРЫ СИМВОЛОВ)
Набор символов в квадратных скобках [ ] именуется символьным классом и позволяет указать
интерпретатору регулярных выражений, что на данном месте в строке может стоять один из
перечисленных символов. В частности, [абв] задаёт возможность появления в тексте одного из трёх
указанных символов, а [1234567890] задаёт соответствие одной из цифр. Возможно указание
диапазонов символов: например, [А-Яа-я] соответствует всем буквам русского алфавита, за
исключением букв «Ё» и «ё».
Если требуется указать символы, которые не входят в указанный набор, то используют символ ^
внутри квадратных скобок, например [^0-9] означает любой символ, кроме цифр.
Некоторые символьные классы можно заменить специальными метасимволами:
ПОЗИЦИЯ ВНУТРИ СТРОКИ
Следующие символы позволяют спозиционировать регулярное выражение относительно
элементов текста: начала и конца строки, границ слова.
КВАНТИФИКАЦИЯ (ПОИСК ПОСЛЕДОВАТЕЛЬНОСТЕЙ)
Квантификатор после символа, символьного класса или группы определяет, сколько раз
предшествующее выражение может встречаться. Следует учитывать, что квантификатор может
относиться более чем к одному символу в регулярном выражении, только если это символьный
класс или группа.
3. Ква́нтор — общее название для логических операций, ограничивающих область истинности
какого-либо предиката и создающих высказывание.
Часто используется последовательность .* для обозначения любого количества любых символов
между двумя частями регулярного выражения.
Если символы { } не образуют квантификатор, их специальное значение игнорируется.
УПРАВЛЯЮЩИЕ СИМВОЛЫ
4. ОБОЗНАЧЕНИЕ ГРУППЫ
Круглые скобки используются для определения области действия и приоритета операций. Шаблон
внутри группы обрабатывается как единое целое и может быть квантифицирован. Например,
выражение (тр[ау]м-?)* найдёт последовательность вида трам-трам-трумтрам-трум-трамтрум.
МОДИФИКАТОРЫ
Модификаторы действуют с момента вхождения и до конца регулярного выражения или
противоположного модификатора. Некоторые интерпретаторы могут применить модификатор ко
всему выражению, а не с момента его вхождения.
Группы-модификаторы можно объединять в одну группу: (?i-sm). Такая группа включает режим i и
выключает режим s, m. Если использование модификаторов требуется только в пределах группы,
то нужный шаблон указывается внутри группы после модификаторов но перед двоеточием.
Например, (?-i)(?i:tv)set найдёт TVset, но не TVSET.
ПЕРЕЧИСЛЕНИЕ
Вертикальная черта разделяет допустимые варианты. Например, gray|grey соответствует gray или
grey. Следует помнить, что перебор вариантов выполняется слева направо, как они указаны.
Если требуется указать перечень вариантов внутри более сложного регулярного выражения, то его
нужно заключить в группу. Например, gray|grey или gr(a|e)y описывают строку gray или grey. В
случае с односимвольными альтернативами предпочтителен вариант gr[ae]y, так как сравнение с
символьным классом выполняется проще, чем обработка группы с проверкой на все её
возможные модификаторы и генерацией обратной связи.
5. ПРОСМОТР ВПЕРЁД И НАЗАД
В большинстве реализаций регулярных выражений есть способ производить поиск фрагмента
текста, «просматривая» (но не включая в найденное) окружающий текст, который расположен до
или после искомого фрагмента текста. Например, таким способом легко найти имя тега HTML, не
включая в результат поиска окружающие его угловые скобки или другие знаки, но и не упуская их
«из внимания» при поиске нужного контекста. Просмотр с отрицанием используется реже и
«следит» за тем, чтобы указанные соответствия, напротив, не встречались до или после искомого
текстового фрагмента.
ПОИСК ПО УСЛОВИЮ
Во многих реализациях регулярных выражений существует возможность выбирать, по какому пути
пойдёт проверка в том или ином месте регулярного выражения на основании уже найденных
значений.
6. 3 ИСПОЛЬЗОВАНИЕ РЕГУЛЯРНЫХ ВЫРАЖЕНИЙ В C++ 11
Для использования регулярных выражений в C++ необходимо подключить стандартную
библиотеку regex. Основные функции для работы содержатся в пространстве имен std.
Функциями, используемыми для применения регулярных выражений являются:
regex_match – проверяет соответствие всей последовательности символов
регулярному выражению
regex_search – проверяет регулярное выражение в любой части
последовательности
regex_replace – заменяет найденный символы, найденные регулярным
выражением форматированной строкой.
REGEX_MATCH
Функция regex_match проверяет всю строку на соответствие регулярному выражению, и
возвращает true, если они совпадают.
Regex_match имеет множество прототипов, одним из вариантов использования является данный
прототип
template <class ST, class SA, char charT, class traits>
bool regex_match (const basic_string<charT,ST,SA>& s, const basic_regex<charT,traits>& rgx,
regex_constants::match_flag_type flags = regex_constants::match_default);
Пояснение
Первый аргумент – строка типа string, в которой будем производить поиск
Второй аргумент – объект класса regex, в котором записано регулярное выражение
Третий аргумент – необязательное поле для флагов
Например, эту функцию можно записать так:
std::string s ("1");
std::regex e ("[[:digit:]]"");
bool search = std::regex_match (s,e);
7. Пример:
Напишем программу, которая будет проверять, записано в строке целое число, или любой другой
набор символов.
Регулярным выражением для поиска числа будет данное выражение ("-?[[:digit:]]+")
-? – говорит о том, что первым символом может быть минус
[[:digit:]] – будем искать исключительно числовые символы (0-9)
+ – это значит, что числовых символов может быть больше одного
Тогда программа будет иметь такой вид:
REGEX_SEARCH
Данная функция работает аналогично функции regex_search, с тем отличием, что тут проверяется не полное
соответствие строки регулярному выражению, true будет возвращено и при частичном совпадении. Прототип
функции совпадает с предыдущим примером.
template <class ST, class SA, char charT, class traits>
bool regex_search (const basic_string<charT,ST,SA>& s, const basic_regex<charT,traits>& rgx,
regex_constants::match_flag_type flags = regex_constants::match_default);
8. Пример:
Эта программа будет искать все слова с частью “ello”. Регулярное выражение
будет очень простым, и иметь вид “ello”
REGEX_REPLACE
Функция regex_replace производит поиск поиск в строке по заданному регулярному выражению и
производит замену найденных значений на заданную строку. Прототип функции имеет вид:
template <class traits, class charT, class ST, class SA>
basic_string<charT> regex_replace (const charT*s,const basic_regex<charT,traits>& rgx, const
basic_string<charT,ST,SA>& fmt, regex_constants::match_flag_type flags = regex_constants::match_default);
Первый аргумент – строка типа string, в которой будем производить поиск
Второй аргумент – объект класса regex, в котором записано регулярное выражение
Третий аргумент – строка типа string, в которая будет замещать найденные значения
Четвертый аргумент - необязательное поле для флагов
Пример записи функции:
regex_replace(input_string, regular_expression, replace_string);
9. Пример:
Напишем программу, которая будет заменять слово “world” в исходной строке на слово “planet”.
Регулярное выражение будет иметь вид “world”.