I have this csv line
std::string s = R"(1997,Ford,E350,"ac, abs, moon","some "rusty" parts",3000.00)";
I can parse it using boost::tokenizer
:
typedef boost::tokenizer< boost::escaped_list_separator<char> , std::string::const_iterator, std::string> Tokenizer;
boost::escaped_list_separator<char> seps('\', ',', '"');
Tokenizer tok(s, seps);
for (auto i : tok)
{
std::cout << i << std::endl;
}
It gets it right except token "rusty" should have double quotes which are getting stripped.
Here is my attempt to use boost::spirit
boost::spirit::classic::rule<> list_csv_item = !(boost::spirit::classic::confix_p('"', *boost::spirit::classic::c_escape_ch_p, '"') | boost::spirit::classic::longest_d[boost::spirit::classic::real_p | boost::spirit::classic::int_p]);
std::vector<std::string> vec_item;
std::vector<std::string> vec_list;
boost::spirit::classic::rule<> list_csv = boost::spirit::classic::list_p(list_csv_item[boost::spirit::classic::push_back_a(vec_item)],',')[boost::spirit::classic::push_back_a(vec_list)];
boost::spirit::classic::parse_info<> result = parse(s.c_str(), list_csv);
if (result.hit)
{
for (auto i : vec_item)
{
cout << i << endl;
}
}
Problems:
does not work, prints the first token only
why boost::spirit::classic? can't find examples using Spirit V2
the setup is brutal .. but I can live with this
** I really want to use boost::spirit
because it tends to be pretty fast
Expected output:
1997
Ford
E350
ac, abs, moon
some "rusty" parts
3000.00
See Question&Answers more detail:os