Заметил, что тут отсутствует хотя бы маленький пример парсинга для приложений на C++, поэтому сейчас это поправим. Сразу говорю, статья не претендует на раскрытие каких то тайн или очень обширный обзор. Статья написана для тех, кто столкнулся с проблемой и вообще не в курсе, как ее решать. И это моя первая статья, так что не судите строго
Для примера будут использоваться классы и функции библиотеки boost::regex и ставшая частью стандарта С++11 библиотека regex. В рамках статьи будет дано очень краткое описание необходимых функций и типов, показан пример использования (придумать что-то абстрактное я не смог, поэтому покажу реальную задачку, которую решал).
Для начала, надо ознакомится с тем, что из себя представляют регулярные выражения, в объеме, хотя бы статьи из википедии ([Ссылки могут видеть только зарегистрированные пользователи. ]).
Для тех, кто собирается использовать boost, надо выполнить несколько предварительных действий:
1. Скачать boost ([Ссылки могут видеть только зарегистрированные пользователи. ]) и установить.
2. Собрать библиотеку RegEx ([Ссылки могут видеть только зарегистрированные пользователи. ])
3. В свойствах проекта дописать дополнительную директорию для поиска заголовочников и библиотек (%path_to_boost%\ и %path_to_boost%\stage\lib соответственно).
4. Для упрощения использования дописываем "using namespace boost" под инклюдами в файле, где будет использоваться, или же просто заменяем (std: на (boost: ко всем типам и функциям, которые будут описаны ниже.
На решение задачки из примера нам понадобятся следующие классы и функции:
Классы:
std::regex - класс, объект которого является регулярным выражением.
std::match_results - класс, объект которого является массивом объектов класса sub_match, который в свою очередь, не более чем объект-хранитель итераторов на начало и конец найденного соответствия в строке. Используется в качестве параметра "результаты_нахождения_соответствий".
Метод:
std::regex_match (или просто std::smatch)- данный алгоритм предназначен для поиска подстроки в исходной строке, по заданному регулярному выражению.
Формат использования выглядит следующим образом:
std::regex_search(std::string входящая_строка, std::regex_match [результаты_нахождения_соответствий], std::regex регулярное_выражение, [флаги]).
[Флаги] — необязательный параметр, с дефолтовым значением match_default. Флаги комбинируются посредством '|'(or). Подробности [Ссылки могут видеть только зарегистрированные пользователи. ].
Из особенностей использования функции стоит отметить, что нулевой член массива всегда содержит количества совпадений, а с первого и далее идут итераторы на начало совпадения испходного текста с регулярным выражением.
Когда нужно искать скажем не по все файлу, а блоками, удобно использовать перегруженный вариант функции, где вместо всего объекта std::string передается два интератора, которые указывают на начало и конец блока текста, в котором нужно искать.
Ну и теперь небольшой пример использования, всего описанного. Сразу оговорюсь, я человек ленивый, поэтому у меня прописано "using namespace std", чтобы не писать для каждой библиотечной функции уточнение пространства имен ( std:: ).
Постановка задачи: имеется текстовый файл со списком стим-айди. Проверить какие из них забанены на ЕАС и вывести в другой файл отчет с указанием причины бана, если бан имеется.
Принцип работы:
1. Скачиваем в файл страничку.
2. Загружаем весь файл в объект класса std::string по символу.
3. Используем библиотеку regex, чтобы проверить, есть ли бан, и, если есть, "вытащить" из скаченного файла коментарий к бану.
Основная функция:
Код:
...
const regex sPatternBan("\\[BEGIN LIST\\]\\s(.*)\\s\\[END OF LIST\\]");
...
bool IsBanned(string& sGUID)
{
DWORD dwResult = 0;
string sEACUrl;
string sFile;
smatch match;
ifstream fBan;
sEACUrl = "http://www.easyanticheat.net/check_guid.php?id=" + sGUID; //Формируем URL для проверки стим-айди
dwResult = URLDownloadToFileA(NULL,sEACUrl.c_str(),"asdb.txt",NULL,NULL); // Скачиваем в файл результат проверки (интернет страница)
if (dwResult != S_OK) // Если неудачно, то выходим
return false;
fBan.open("asdb.txt");
dwResult = LoadFile(sFile,fBan); // Загружаем файл в объект класса std::string
fBan.close();
if (dwResult) // Если не получилось, то выходим
return false;
dwResult = regex_search(sFile,match,sPatternBan); // Собственно ищем соответствие заданному регулярному выражению
fout << match[1] << '\n';
return static_cast<bool>(dwResult);
}
Если есть вопросы задавайте, постараюсь ответить.
В дополнение к статье и просто для тех, кому ничего нового не поведал, немного информации по теме:
1. [Ссылки могут видеть только зарегистрированные пользователи. ]
2. [Ссылки могут видеть только зарегистрированные пользователи. ]
3. [Ссылки могут видеть только зарегистрированные пользователи. ]
4. [Ссылки могут видеть только зарегистрированные пользователи. ]
5. [Ссылки могут видеть только зарегистрированные пользователи. ]
6. [Ссылки могут видеть только зарегистрированные пользователи. ]
7. [Ссылки могут видеть только зарегистрированные пользователи. ]
Спасибо за внимание.
Полный исходник и тестовый файлик прилагаются.
Последний раз редактировалось twice; 06.09.2013 в 15:00.