Чтение онлайн

на главную

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

(\w{2}\d{5})|(\w{2}\d{5}–\d{4})

и

(\w{2}\d{5})(–\d{4})?

Как и фигурные скобки при обозначении счетчиков (например, \w{2}), знак вопроса (?) используется как суффикс. Например, (–\d{4})? означает “необязательно –\d{4}”; т.е. мы интерпретируем четыре цифры, перед которыми стоит дефис, как суффикс. На самом деле мы не используем круглые скобки для выделения пятизначного почтового кода ZIP (\w{2}\d{5}) для выполнения какой-либо операции, поэтому их можно удалить.

\w{2}\d{5}(–\d{4})?

Для

того чтобы завершить наше решение задачи, поставленной в разделе 23.5, можем добавить необязательный пробел после двух букв.

\w{2} ?\d{5}(–\d{4})?

Запись “?” выглядит довольно странно, но знак вопроса после пробела указывает на то, что пробел является необязательным. Если бы мы хотели, чтобы пробел не выглядел опечаткой, то должны были бы заключить его в скобки.

\w{2}?\d{5}((–\d{4})?

Если бы кто-то сказал, что эта запись выглядит слишком неразборчивой, то нам пришлось бы придумать обозначение для пробела, например \s (s — от слова “space”). В этом случае запись выглядела бы так:

\w{2}\s?\d{5}(–\d{4})?

А что если кто-то поставит два пробела после букв? В соответствии с определенным выше шаблоном это означало бы, что мы принимаем коды TX77845 и TX 77845, но не TX 77845. Это неправильно.

Нам нужно средство, чтобы сказать “ни одного, один или несколько пробелов”, поэтому мы вводим суффикс *.

\w{2}\s*\d{5}(–\d{4})?

Было бы целесообразно выполнять каждый этап в строгой логической последовательности. Эта система обозначения логична и очень лаконична. Кроме того, мы не принимали проектные решения с потолка: выбранная нами система обозначений очень широко распространена. При решении большинства задач, связанных с обработкой текста, нам необходимо читать и записывать эти символы. Да, эти записи похожи на результат прогулки кошки по клавиатуре, и ошибка в единственном месте (наш лишний или пропущенный пробел) полностью изменяет их смысл, но с этим приходится смириться. Мы не можем предложить ничего радикально лучшего, и этот стиль обозначений за тридцать лет распространился очень широко. Впервые он был использован в команде
grep
в системе Unix, но и даже тогда его нельзя было назвать совершенно новым.

23.7. Поиск с помощью регулярных выражений

Теперь применим шаблон почтовых кодов ZIP из предыдущего раздела для поиска почтовых кодов в файле. Программа определяет шаблон, а затем ищет его, считывая файл строка за строкой. Когда программа находит шаблон в какой-то строке, она выводит номер строки и найденный код.

#include <boost/regex.hpp>

#include <iostream>

#include <string>

#include <fstream>

using namespace std;

int main

{

ifstream in("file.txt"); // файл ввода

if (!in) cerr << "нет файла \n";

boost::regex pat ("\\w{2}\\s*\\d{5}(–\\d{4})?"); //
шаблон

// кода ZIP

cout << "шаблон: " << pat << '\n';

int lineno = 0;

string line; // буфер ввода

while (getline(in,line)) {

++lineno;

boost::smatch matches; // записываем сюда совпавшие строки

if (boost::regex_search(line, matches, pat))

cout << lineno << ": " << matches[0] << '\n';

}

}

Эта программа требует объяснений. Сначала рассмотрим следующий фрагмент:

#include <boost/regex.hpp>

...

boost::regex pat ("\\w{2}\\s*\\d{5}(–\\d{4})?"); // шаблон кода ZIP

boost::smatch matches; // записываем сюда совпавшие строки

if (boost::regex_search(line, matches, pat))

Мы используем реализацию библиотеки

Boost.Regex
, которая скоро станет частью стандартной библиотеки. Для того чтобы использовать библиотеку
Boost.Regex
, ее необходимо инсталлировать. Для того чтобы показать, какие возможности относятся к библиотеке
Boost.Regex
, мы явно указываем пространство имен
boost
в качестве квалификатора, т.е.
boost::regex
.

Вернемся к регулярным выражениям! Рассмотрим следующий фрагмент кода:

boost::regex pat ("\\w{2}\\s*\\d{5}(–\\d{4})?");

cout << "шаблон: " << pat << '\n';

Здесь мы сначала определили шаблон

pat
(типа
regex
), а затем вывели его на печать. Обратите внимание на то, что мы написали:

\\w{2}\\s*\\d{5}(–\\d{4})?

Если бы вы запустили программу, то увидели бы на экране следующую строку:

pattern: \w{2}\s*\d{5}(–\d{4})?

В строковых литералах языка С++ обратная косая черта означает управляющий символ (раздел A.2.4), поэтому вместо одной обратной косой черты (\) в литеральной строке необходимо написать две (\\).

Шаблон типа
regex
на самом деле является разновидностью объекта класса
string
, поэтому мы можем вывести его на печать с помощью оператора
<<
. Класс
regex
— это не просто разновидность класса
string
, но его довольно сложный механизм сопоставления шаблонов, созданных при инициализации объекта класса
regex
(или при выполнении оператора присваивания), выходит за рамки рассмотрения нашей книги. Однако, поскольку мы инициализировали объект класса
regex
шаблоном почтовых кодов, можем применить его к каждой строке нашего файла.

Поделиться:
Популярные книги

Столичный доктор. Том III

Вязовский Алексей
3. Столичный доктор
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Столичный доктор. Том III

Бремя империи

Афанасьев Александр
Бремя империи - 1.
Фантастика:
альтернативная история
9.34
рейтинг книги
Бремя империи

На границе империй. Том 9. Часть 2

INDIGO
15. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 2

Герцогиня в ссылке

Нова Юлия
2. Магия стихий
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Герцогиня в ссылке

Помещица Бедная Лиза

Шах Ольга
Любовные романы:
любовно-фантастические романы
6.40
рейтинг книги
Помещица Бедная Лиза

Менталист. Конфронтация

Еслер Андрей
2. Выиграть у времени
Фантастика:
боевая фантастика
6.90
рейтинг книги
Менталист. Конфронтация

В теле пацана 4

Павлов Игорь Васильевич
4. Великое плато Вита
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
В теле пацана 4

Я уже князь. Книга XIX

Дрейк Сириус
19. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я уже князь. Книга XIX

Последняя Арена 5

Греков Сергей
5. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 5

Пистоль и шпага

Дроздов Анатолий Федорович
2. Штуцер и тесак
Фантастика:
альтернативная история
8.28
рейтинг книги
Пистоль и шпага

Гром над Империей. Часть 1

Машуков Тимур
5. Гром над миром
Фантастика:
фэнтези
5.20
рейтинг книги
Гром над Империей. Часть 1

Ночь со зверем

Владимирова Анна
3. Оборотни-медведи
Любовные романы:
любовно-фантастические романы
5.25
рейтинг книги
Ночь со зверем

Везунчик. Проводник

Бубела Олег Николаевич
3. Везунчик
Фантастика:
фэнтези
6.62
рейтинг книги
Везунчик. Проводник

Шесть тайных свиданий мисс Недотроги

Суббота Светлана
Любовные романы:
любовно-фантастические романы
эро литература
7.75
рейтинг книги
Шесть тайных свиданий мисс Недотроги