- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Язык программирования C++. Пятое издание - Стенли Липпман
Шрифт:
Интервал:
Закладка:
Упражнение 17.21. Перепишите программу номеров телефонов из раздела 8.3.2 так, чтобы использовать функцию valid(), определенную в этом разделе.
Упражнение 17.22. Перепишите программу номеров телефонов так, чтобы она позволила разделять три части номера телефона любыми символами.
Упражнение 17.23. Напишите регулярное выражение для поиска почтовых индексов. У них может быть пять или девять цифр. Первые пять цифр могут быть отделены от остальных четырех тире.
17.3.4. Использование функции regex_replace()
Регулярные выражения зачастую используются не только для поиска, но и для замены одной последовательности другой. Например, может потребоваться преобразовать американские номера телефонов в формат "ddd.ddd.dddd", где код города и три последующие цифры разделены точками.
Когда необходимо найти и заменить регулярное выражение в исходной последовательности, используется функция regex_replace(). Подобно функции поиска, функция regex_replace(), описанная в табл. 17.12, получает входную символьную последовательность и объект класса regex. Следует также передать строку, которая описывает необходимый вывод.
Таблица 17.12. Функции замены регулярного выражения
m.format(dest, fmt, mft) m.format(fmt, mft) Создает форматированный вывод, используя формат строки fmt, соответствие в m и необязательные флаги match_flag_type в mft. Первая версия пишет в итератор вывода dest (см. раздел 10.5.1) и получает формат fmt, который может быть строкой или парой указателей, обозначающих диапазон в символьном массиве. Вторая версия возвращает строку, которая содержит вывод и получает формат fmt, являющийся строкой или указателем на символьный массив с нулевым символом в конце. По умолчанию mft имеет значение format_default regex_replace(dest, seq, r, fmt, mft) regex_replace(seq, r, fmt, mft) Перебирает последовательность seq, используя функцию regex_search() для поиска соответствий объекту r класса regex. Использует формат строки fmt и необязательные флаги match_flag_type в mft для формирования вывода. Первая версия пишет в итератор вывода dest и получает пару итераторов для обозначения последовательности seq. Вторая возвращает строку, содержащую вывод, a seq может быть строкой или указателем на символьный массив с нулевым символом в конце. Во всех случаях формат fmt может быть строкой или указателем на символьный массив с нулевым символом в конце. По умолчанию mft имеет значение match_defaultСтроку замены составляют подлежащие включению символы вместе с подвыражениями из соответствующей подстроки. В данном случае следует использовать второе, пятое и седьмое подвыражения из строки замены. Первое, третье, четвертое и шестое подвыражения игнорируются, поскольку они использовались в первоначальном форматировании номера, но не являются частью формата замены. Для ссылки на конкретное подвыражение используется символ $, сопровождаемый индексом подвыражения:
string fmt = "$2.$5.$7"; // переформатировать номера в ddd.ddd.dddd
Схему регулярного выражения и строку замены можно использовать следующим образом:
regex r(phone); // regex для поиска схемы
string number = "(908) 555-1800";
cout << regex_replace(number, r, fmt) << endl;
Вывод этой программы будет таким:
908.555.1800
Замена только части исходной последовательностиКуда интересней использование обработки регулярных выражений для замены номеров телефонов в большом файле. Предположим, например, что имеется файл имен и номеров телефонов, содержащий такие данные:
morgan (201) 555-2368 862-555-0123/
drew (973)555.0130
lee (609) 555-0132 2015550175 800.555-0000
Их следует преобразовать в такой формат:
morgan 201.555.2368 862.555.0123
drew 973.555.0130
lee 609.555.0132 201.555.0175 800.555.0000
Это преобразование можно осуществить следующим образом:
int main() {
string phone =
"(\()?(\d{3})(\))?([-. ])?(\d{3})([-. ])?(\d{4})";
regex r(phone); // regex для поиска схемы
smatch m;
string s;
string fmt = "$2.$5.$7"; // переформатировать номера в ddd.ddd.dddd
// прочитать каждую запись из входного файла
while (getline(cin, s))
cout << regex_replace(s, r, fmt) << endl;
return 0;
}
Каждая запись читается в строку s и передается функции regex_replace(). Эта функция находит и преобразует все соответствия исходной последовательности.
Флаги, контролирующие соответствия и форматКроме флагов обработки регулярных выражений, библиотека определяет также флаги, позволяющие контролировать процесс поиска соответствия и форматирования при замене. Их значения приведены в табл. 17.13. Эти флаги могут быть переданы функции regex_search(), или функции regex_match(), или функциям-членам формата класса smatch.
Таблица 17.13. Флаги соответствия
Определено в regex_constants::match_flag_type match_default Эквивалент format_default match_not_bol He рассматривать первый символ как начало строки match_not_eol Не рассматривать последний символ как конец строки match_not_bow Не рассматривать первый символ как начало слова match_not_eow Не рассматривать последний символ как конец слова match_any Если соответствий несколько, может быть возвращено любое из них match_not_null Не соответствует пустой последовательности match_continuous Соответствие должно начинаться с первого символа во вводе match_prev_avail У исходной последовательности есть символы перед первым format_default Строка замены использует правила ECMAScript format_sed Строка замены использует правила POSIX sed format_no_copy Не выводить несоответствующие части ввода format_first_only Заменить только первое вхождениеФлаги соответствия и формата имеют тип match_flag_type. Их значения определяются в пространстве имен regex_constants. Подобно пространству имен placeholders, используемому с функциями bind() (см. раздел 10.3.4), пространство имен regex_constants определено в пространстве имен std. Для использования имени из пространства regex_constants его следует квалифицировать именами обоих пространств имен:
using std::regex_constants::format_no_copy;
Это объявление указывает, что когда код использует флаг format_no_copy, необходим объект из пространства имен std::regex_constants. Вместо этого можно использовать и альтернативную форму using, рассматриваемую в разделе 18.2.2:
using namespace std::regex_constants;
Использование флагов форматаПо умолчанию функция regex_replace() выводит всю исходную последовательность. Части, которые не соответствуют регулярному выражению, выводятся без изменений, а соответствующие части оформляются, как указано строкой формата. Это стандартное поведение можно изменить, указав флаг format_no_copy в вызове функции regex_replace():
// выдать только номера телефона: используется новая строка формата
string fmt2 = "$2.$5.$7 "; // поместить пробел как разделитель после
// последнего числа
// указать regex_replace() копировать только заменяемый текст
cout << regex_replace(s, r, fmt2, format_no_copy) << endl;
С учетом того же ввода эта версия программы создает такой вывод:

