【发布时间】:2015-06-11 13:09:00
【问题描述】:
我有一个文件,其中包含一些 Valve 格式的“实体”数据。它基本上是一个键值交易,它看起来像这样:
{
"world_maxs" "3432 4096 822"
"world_mins" "-2408 -4096 -571"
"skyname" "sky_alpinestorm_01"
"maxpropscreenwidth" "-1"
"detailvbsp" "detail_sawmill.vbsp"
"detailmaterial" "detail/detailsprites_sawmill"
"classname" "worldspawn"
"mapversion" "1371"
"hammerid" "1"
}
{
"origin" "553 -441 322"
"targetname" "tonemap_global"
"classname" "env_tonemap_controller"
"hammerid" "90580"
}
每一对{} 算作一个实体,其中的行算作KeyValues。如您所见,它相当简单。
我想在 C++ 中将这些数据处理成vector<map<string, string> >。为此,我尝试使用 Boost 附带的正则表达式。这是我目前所拥有的:
static const boost::regex entityRegex("\\{(\\s*\"([A-Za-z0-9_]+)\"\\s*\"([^\"]+)\")+\\s*\\}");
boost::smatch what;
while (regex_search(entitiesString, what, entityRegex)) {
cout << what[0] << endl;
cout << what[1] << endl;
cout << what[2] << endl;
cout << what[3] << endl;
break; // TODO
}
更易于阅读的正则表达式:
\{(\s*"([A-Za-z0-9_]+)"\s*"([^"]+)")+\s*\}
我还不确定正则表达式是否适合我的问题,但它似乎至少打印了最后一个键值对 (hammerid, 1)。
我的问题是,我将如何在表达式中提取“第 n 个”匹配的子表达式?还是没有真正实用的方法来做到这一点?编写两个嵌套的while-loop 会更好吗,一个搜索{} 模式,然后一个搜索实际的键值对?
谢谢!
【问题讨论】:
-
不要使用正则表达式。使用语法。我会在一分钟内告诉你
-
Boost 正则表达式在这里表现不佳。您首先需要extract the
{...}part,然后在其中使用"([A-Za-z0-9_]+?)"\s*?"([^"]+?)"。 Like this. -
非常有趣的网站!感谢那。我会看看@sehe 对语法的看法。