我想使用boost精神解析以下字符串:
"{"DeliverNr":7424,"fruits":[["apple","banana","orange", "raspberry"]]}"
但是我想把矢量只放在三个第一个果实中。
我有以下输出:
it: { , dist: 0
有谁能告诉我我做错了什么?
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/foreach.hpp>
#include <iostream>
#include <vector>
struct SomeStructF
{
std::string str1, str2, str3;
};
using namespace boost::spirit;
qi::rule<std::string::iterator> startRule;
qi::rule<std::string::iterator> endRule;
qi::rule<std::string::iterator, std::string()> stringRule;
qi::rule<std::string::iterator, SomeStructF()> valueRule;
qi::rule<std::string::iterator, std::vector<SomeStructF>()> valuesRule;
char const QUOTATION_MARK{ '"' };
char const OPEN_SQUARE_BRACKET{ '[' };
startRule =
+(qi::char_ - qi::char_(OPEN_SQUARE_BRACKET))
>> qi::char_(OPEN_SQUARE_BRACKET);
endRule = +qi::char_;
stringRule =
QUOTATION_MARK
>> *(qi::char_ - QUOTATION_MARK)
>> QUOTATION_MARK;
valueRule =
OPEN_SQUARE_BRACKET
>> stringRule
>> stringRule
>> stringRule;
valuesRule %=
startRule
>> valueRule
>> endRule;
std::vector<SomeStructF> res;
auto it = data.begin();
if (qi::parse(it, data.end(), valuesRule, res))
{
std::cout << "PARSE succeded" << std::endl;
}
std::cout << "it: " << *it << " , dist: " << std::distance(data.begin(), it) << std::endl;
std::cout << "res size " << res.size() << std::endl;
BOOST_FUSION_ADAPT_STRUCT(
parsers::SomeStructF,
(std::string, str1)
(std::string, str2)
(std::string, str3)
)
答案 0 :(得分:4)
我不是特别清楚你在问什么。在我看来,正如你所指出的那样,很容易将逗号用于逗号:
<强> Live On Coliru 强>
#define BOOST_SPIRIT_DEBUG
#include <iostream>
#include <vector>
#include <string>
#include <iterator>
#include <iomanip>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
namespace qi = boost::spirit::qi;
struct SomeStructF {
std::string str1, str2, str3;
};
BOOST_FUSION_ADAPT_STRUCT(
SomeStructF,
(std::string, str1)
(std::string, str2)
(std::string, str3)
)
int main()
{
qi::rule<std::string::iterator> startRule;
qi::rule<std::string::iterator> endRule;
qi::rule<std::string::iterator, std::string()> stringRule;
qi::rule<std::string::iterator, SomeStructF()> valueRule;
qi::rule<std::string::iterator, SomeStructF()> valuesRule;
char const QUOTATION_MARK{ '"' };
char const OPEN_SQUARE_BRACKET{ '[' };
startRule =
+(qi::char_ - qi::char_(OPEN_SQUARE_BRACKET))
>> qi::char_(OPEN_SQUARE_BRACKET);
endRule = +qi::char_;
stringRule =
QUOTATION_MARK
>> *(qi::char_ - QUOTATION_MARK)
>> QUOTATION_MARK;
valueRule =
OPEN_SQUARE_BRACKET
>> stringRule >> ','
>> stringRule >> ','
>> stringRule;
valuesRule %=
startRule
>> valueRule
>> endRule;
BOOST_SPIRIT_DEBUG_NODES((startRule)(endRule)(stringRule)(valueRule)(valuesRule));
std::string data = R"({"DeliverNr":7424,"fruits":
[["apple","banana","orange","raspberry"]]})";
std::vector<SomeStructF> res;
auto it = data.begin();
if (qi::parse(it, data.end(), valuesRule, res))
{
std::cout << "PARSE succeded" << std::endl;
std::cout << "res size " << res.size() << std::endl;
for (auto& el : res) {
std::cout << "el: {" << std::quoted(el.str1) << ","
<< std::quoted(el.str2) << ","
<< std::quoted(el.str3) << "}\n";
}
}
else
{
std::cout << "Parse did not succeed\n";
}
if (it != data.end())
std::cout << "Remaining unparsed: '" << std::string(it, data.end()) << "'\n";
}
打印
PARSE succeded
res size 1
el: {"apple","banana","orange"}
你的语法(也不是你的问题)显示了你如何检测多个SomeStructF
所以我真的不知道你想要什么。也许你想要简化:
<强> Live On Coliru 强>
using It = std::string::const_iterator;
qi::rule<It, std::string()> quoted_ = '"' >> *~qi::char_('"') >> '"';
qi::rule<It, SomeStructF()/*, qi::space_type*/> value_ = quoted_ >> ',' >> quoted_ >> ',' >> quoted_;
using boost::spirit::repository::qi::seek;
BOOST_SPIRIT_DEBUG_NODES((quoted_)(value_));
std::string const data = R"({"DeliverNr":7424,"fruits":[["apple","banana","orange","raspberry"]]}
{"DeliverNr":7435,"botanics":[["pine","maple","oak","pernambucco"]]})";
std::vector<SomeStructF> res;
It it = data.begin();
if (qi::phrase_parse(it, data.end(), *seek["[[" >> value_], qi::space, res)) {
for (auto& el : res) {
std::cout << "el: {" << std::quoted(el.str1) << ","
<< std::quoted(el.str2) << ","
<< std::quoted(el.str3) << "}\n";
}
} else {
std::cout << "Parse did not succeed\n";
}
打印
el: {"apple","banana","orange"}
el: {"pine","maple","oak"}
Remaining unparsed: ',"pernambucco"]]}'