Сначала загляните в библиотеку boost::date_time
. Он имеет систему ввода-вывода , которая может быть тем, что вы хотите, но я вижу отсутствие поиска.
Для пользовательского поиска по дате вам нужно boost::xpressive
. Он содержит все, что вам нужно. Давайте посмотрим на мой наспех написанный пример. Сначала вы должны разобрать свой собственный шаблон, ведь с Xpressive это просто. Сначала посмотрите на заголовок, который вам нужен:
#include <string>
#include <iostream>
#include <map>
#include <boost/xpressive/xpressive_static.hpp>
#include <boost/xpressive/regex_actions.hpp>
//make example shorter but less clear
using namespace boost::xpressive;
Второе определение карты ваших специальных тегов:
std::map<std::string, int > number_map;
number_map["%yr"] = 0;
number_map["%mh"] = 1;
number_map["%dy"] = 2;
number_map["%%"] = 3; // escape a %
Следующий шаг - создание регулярного выражения, которое будет анализировать наш шаблон с тегами и сохранять значения из карты в переменную tag_id, когда найдет тег, или сохранить -1 в противном случае:
int tag_id;
sregex rx=((a1=number_map)|(s1=+~as_xpr('%')))[ref(tag_id)=(a1|-1)];
Более подробную информацию и описание смотрите здесь и здесь .
Теперь давайте разберем некоторый шаблон:
std::string pattern("%yr-%mh-%dy"); // this will be parsed
sregex_token_iterator begin( pattern.begin(), pattern.end(), rx ), end;
if(begin == end) throw std::runtime_error("The pattern is empty!");
sregex_token_iterator
будет перебирать наши токены и каждый раз устанавливать переменную tag_id. Все, что нам нужно сделать, это создать регулярное выражение, используя эти токены. Мы построим это регулярное выражение, используя теги соответствующие части статического регулярного выражения, определенного в массиве:
sregex regex_group[] = {
range('1','9') >> repeat<3,3>( _d ), // 4 digit year
as_xpr( "January" ) | "February" | "August", // not all month XD so lazy
repeat<2,2>( range('0','9') )[ // two digit day
check(as<int>(_) >= 1 && as<int>(_) <= 31) ], //only bettwen 1 and 31
as_xpr( '%' ) // match escaped %
};
Наконец, давайте начнем строить наше специальное регулярное выражение. Первый матч построит первую его часть. Если тег совпадает и tag_id неотрицателен, мы выбираем регулярное выражение из массива, иначе совпадение, вероятно, является разделителем, и мы создаем регулярное выражение, которое соответствует ему:
sregex custom_regex = (tag_id>=0) ? regex_group[tag_id] : as_xpr(begin->str());
Далее мы будем перебирать от начала до конца и добавлять следующее регулярное выражение:
while(++begin != end)
{
if(tag_id>=0)
{
sregex nextregex = custom_regex >> regex_group[tag_id];
custom_regex = nextregex;
}
else
{
sregex nextregex = custom_regex >> as_xpr(begin->str());
custom_regex = nextregex;
}
}
Теперь наше регулярное выражение готово, давайте найдем несколько дат: -]
std::string input = "The date is 2009-August-25.";
smatch mydate;
if( regex_search( input, mydate, custom_regex ) )
std::cout << "Found " << mydate.str() << "." << std::endl;
Библиотека xpressive очень мощная и быстрая. Это также красивое использование шаблонов.
Если вам нравится этот пример, дайте мне знать в комментариях или пунктах; -)