【发布时间】:2016-02-23 18:31:00
【问题描述】:
我有一个键值对列表,由 EOL 分隔。
我让 Boost Spirit 为格式正确的行做我想做的事(即"MyKey : MyValue \r\n MyKey2 : MyValue2")。
现在我的问题是我想跳过不符合要求的行。 例如:
This is some title line!
Key1:Value1
Some more gibberish to skip
Key2:Value2
我想出了以下我认为可行的代码,但结果映射为空并且解析失败。
- 在我的
KeyRule中,我添加了“-qi::eol”以避免在遇到第一个KeyValue分隔符之前耗尽无效行。 - 在我的
ItemRule中,PairRule都是可选的,eol是 1 或更多以解决多个断线。
我阅读了以下主题:
Why does parsing a blank line with Spirit produce an empty key value pair in map?
它通过自定义船长跳过注释行(以 # 开头),但在我的
在这种情况下,我想跳过任何不包含键值分隔符: 的行。
必须有一些优雅的东西。
#include <iostream>
#include <string>
#include <map>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/std_pair.hpp>
namespace qi = boost::spirit::qi;
template <typename Iterator, typename Skipper = qi::blank_type>
struct KeyValueParser : qi::grammar<Iterator, std::map<std::string, std::string>(), Skipper> {
KeyValueParser() : KeyValueParser::base_type(ItemRule) {
ItemRule = -PairRule >> *(+qi::eol >> -PairRule) >> -qi::eol;
PairRule = KeyRule >> ':' >> ValueRule;
KeyRule = qi::raw[+(qi::char_ - ':' - qi::eol)];
ValueRule = qi::raw[+(qi::char_ - qi::eol)];
}
qi::rule<Iterator, std::map<std::string, std::string>(), Skipper> ItemRule;
qi::rule<Iterator, std::pair<std::string, std::string>(), Skipper> PairRule;
qi::rule<Iterator, std::string(), Skipper> KeyRule;
qi::rule<Iterator, std::string(), Skipper> ValueRule;
};
int main() {
const std::string input = " Line To Skip! \r\n My Key : Value \r\n My2ndKey : Long Value \r\n";
std::string::const_iterator iter = input.begin(), end = input.end();
KeyValueParser<std::string::const_iterator> parser;
typedef std::map<std::string, std::string> MyMap;
MyMap parsed_map;
bool result = qi::phrase_parse(iter, end, parser, qi::blank, parsed_map);
if (result && (iter == end)) {
std::cout << "Success." << std::endl;
for (MyMap::const_iterator pIter = parsed_map.begin(); pIter != parsed_map.end(); ++pIter) {
std::cout << "\"" << pIter->first << "\" : \"" << pIter->second << "\"" << std::endl;
}
} else {
std::cout << "Something failed. Unparsed: ->|" << std::string(iter, end) << "|<-" << std::endl;
}
getchar();
return 0;
}
【问题讨论】:
标签: c++ boost boost-spirit boost-spirit-qi