例如,我必须在标题中找到格式的时间(但%
- 标签顺序可以不同)在字符串"The date is 2009-August-25."
中如何让程序解释标签和什么结构最好用它们存储有关如何处理某些日期字符串的信息吗?
答案 0 :(得分:1)
我将正则表达式中的标记字符串转换为3个字段的捕获并搜索它。正则表达式的复杂性取决于您希望接受%yr的内容。您也可以使用不太严格的表达式,然后检查有效值,这可能会导致更好的错误消息(“无效月份:Augsut”而不是“未找到日期”)或误报,具体取决于上下文。
答案 1 :(得分:1)
首先查看boost::date_time
库。它有IO system女巫可能是你想要的,但我看到缺乏搜索。
要进行自定义日期搜索,您需要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 %
下一步是创建一个正则表达式,它将使用标记解析我们的模式,并在找到标记时将值从map保存到变量tag_id中,否则保存为-1:
int tag_id;
sregex rx=((a1=number_map)|(s1=+~as_xpr('%')))[ref(tag_id)=(a1|-1)];
更多信息和说明查看here和here。 现在让我们解析一些模式:
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库非常强大且快速。它也是美丽的图案使用。
如果你喜欢这个例子,请在评论或要点告诉我; - )