- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Язык программирования C++. Пятое издание - Стенли Липпман
Шрифт:
Интервал:
Закладка:
В этой программе требуется часть имени перед точкой, что является первым подвыражением, поэтому следует вывести results.str(1).
Подвыражения для проверки правильности данныхПодвыражения обычно используются для проверки данных, которые должны соответствовать некоему определенному формату. Например, в Америке номера телефонов имеют десять цифр, включая код города и местный номер из семи цифр. Код города зачастую, но не всегда, заключен в круглые скобки. Остальные семь цифр могут быть отделены тире, точкой или пробелом либо не отделяться вообще. Данные в некоторых из этих форматов могли бы быть приемлемы, а в других — нет. Процесс будет состоять из двух этапов: сначала используем регулярное выражение для поиска последовательностей, которые могли бы быть номерами телефонов, а затем вызовем функцию для окончательной проверки правильности данных.
Прежде чем написать схему номеров телефона, необходимо рассмотреть еще несколько аспектов языка регулярных выражений на языке ECMAScript.
• {d} представляет одиночную цифру, а {d}{n} — последовательность из n цифр. (Например, {d}{3} соответствует последовательности из трех цифр.)
• Набор символов в квадратных скобках позволяет задать соответствие любому из трех символов. (Например, [-.] соответствует тире, точке или пробелу. Обратите внимание: у точки в квадратных скобках нет никакого специального смысла.)
• Компонент, следующий за символом '?', не обязательный. (Например, {d}{3}[-. ]?{d}{4} соответствует трем цифрам, сопровождаемым опциональными тире, точкой или пробелом и еще четырьмя цифрами. Этой схеме соответствовало бы 555-0132, или 555.0132, или 555 0132, или 5550132).
• Как и в языке С++, в ECMAScript символ за наклонной чертой означает, что он представляет себя, а не специальное значение. Поскольку данная схема включает круглые скобки, являющиеся специальными символами в языке ECMAScript, круглые скобки, являющиеся частью схемы, следует представить как ( или ).
Поскольку наклонная черта влево является специальным символом в языке С++, когда он встречается в схеме, следует добавить вторую наклонную черту, чтобы указать языку С++, что имеется в виду символ . Следовательно, чтобы представить регулярное выражение {d}{3}, нужно написать \{d}{3}.
Для проверки номеров телефонов следует обратиться к компонентам схемы. Например, необходимо проверить, что если номер использует открывающую круглую скобку для кода города, то он использует также закрывающую скобку после него. В результате такой номер, как (908.555.1800, следует отклонить.
Для определения такого соответствия необходимо регулярное выражение, использующее подвыражения. Каждое подвыражение заключается в пару круглых скобок:
// все выражение состоит из семи подвыражений: (ddd) разделитель ddd
// разделитель dddd
// подвыражения 1, 3, 4 и 6 опциональны; а 2, 5 и 7 содержат цифры
"(\()?(\d{3})(\))?([-. ])?(\d{3})([-. ]?)(\d{4})";
Поскольку схема использует круглые скобки, а также из-за использования наклонных черт, эту схему трудно прочитать (и написать!). Проще всего прочитать ее по каждому отдельному (заключенному в скобки) подвыражению.
1. (\()? необязательная открывающая скобка для кода города.
2. (\d{3}) код города.
3. (\))? необязательная закрывающая скобка для кода города.
4. ([-. ])? необязательный разделитель после кода города.
5. (\d{3}) следующие три цифры номера.
6. ([-. ])? другой необязательный разделитель.
7. (\d{4}) последние четыре цифры номера.
Следующий код использует эту схему для чтения файла и находит данные, соответствующие общей схеме телефонных номеров. Для проверки допустимости формата номеров используется функция valid():
string phone =
"(\()?(\d{3})(\))?([-. ])?(\d{3})([-. ]?)(\d{4})";
regex r(phone); // объект regex для поиска схемы
smatch m;
string s;
// прочитать все записи из входного файла
while (getline(cin, s)) {
// для каждого подходящего номера телефона
for (sregex_iterator it(s.begin(), s.end(), r), end_it;
it != end_it; ++it)
// проверить допустимость формата номера
if (valid(*it))
cout << "valid: " << it->str() << endl;
else
cout << "not valid: " << it->str() << endl;
}
Операции с типом соответствияНапишем функцию valid(), используя операции типа соответствия, приведенные в табл. 17.11. Не следует забывать, что схема pattern состоит из семи подвыражений. В результате каждый объект класса smatch будет содержать восемь элементов ssub_match. Элемент [0] представляет общее соответствие, а элементы [1] - [7] представляют каждое из соответствующих подвыражений.
Таблица 17.11. Операции с типом соответствия
Эти операции применимы к типам ssub_match, csub_match, wssub_match и wcsub_match matched Открытая логическая переменная-член, означающая соответствие объекта класса ssub_match first second Открытые переменные-члены, являющиеся итераторами на начало последовательности соответствия и ее следующий элемент после последнего. Если соответствия нет, то first и second равны length() Размер текущего объекта соответствия. Возвращает 0, если переменная-член matched содержит значение false str() Возвращает строку, содержащую соответствующую часть ввода. Возвращает пустую строку, если переменная-член matched содержит значение false s = ssub Преобразует объект ssub класса ssub_match в строку s. Эквивалент вызова s = ssub.str(). Оператор преобразования не является явным (см. раздел 14.9.1)Когда происходит вызов функции valid(), известно, что общее соответствие имеется, но неизвестно, какие из необязательных подвыражений являются частью этого соответствия. Переменная-член matched класса ssub_match, соответствующая определенному подвыражению, содержит значение true, если это подвыражение является частью общего соответствия.
В правильном номере телефона код города либо полностью заключается в скобки, либо не заключается в них вообще. Поэтому действие функции valid() зависит от того, начинается ли номер с круглой скобки или нет:
bool valid(const smatch& m) {
// если перед кодом города есть открывающая скобка
if (m[1].matched)
// за кодом города должна быть закрывающая скобка
// и остальная часть номера непосредственно или через пробел
return m[3].matched
&& (m[4].matched == 0 || m[4].str() == " ");
else
// здесь после кода города не может быть закрывающей скобки
// но разделители между другими двумя компонентами должны быть
// корректны
return !m[3].matched
&& m[4].str() == m[6].str();
}
Начнем с проверки соответствия первому подвыражению (т.е. открывающей скобки). Это подвыражение находится в элементе m[1]. Если это соответствие есть, то номер начинается с открывающей скобки. В таком случае номер будет допустимым, только если подвыражение после кода города также будет соответствующим (т.е. будет закрывающая скобка после кода города). Кроме того, если скобки в начале номера корректны, то следующим символом должен быть пробел или первая цифра следующей части номера.
Если элемент m[1] не соответствует (т.е. открывающей скобки нет), то подвыражение после кода города также должно быть пустым. Если это так и если остальные разделители совпадают, то номер допустим, но не в противном случае.
Упражнения раздела 17.3.3Упражнение 17.19. Почему можно вызывать функцию m[4].str() без предварительной проверки соответствия элемента m[4]?
Упражнение 17.20. Напишите собственную версию программы для проверки номеров телефонов.
Упражнение 17.21. Перепишите программу номеров телефонов из раздела 8.3.2 так, чтобы использовать функцию valid(), определенную в этом разделе.

