Как разобрать номер после нахождения какого-то слова

Я хочу разобрать упомянутый JSON и извлечь из него значение года производства

    auto data = {
"cars" : [
{
"name" : "BMW",
"engine" : 3.0
},
{
"name" : "Citroen",
"engine" : 3.6
},
{
"name" : "Ferrari",
"engine" : 4.2
}
],
"productionYear" : 1999
}

и у меня есть следующее правило для этого:

    using boost::spirit::ascii::string;
using boost::spirit::omit;
using boost::spirit::qi::lit;
using boost::spirit::qi::char_;

boost::spirit::qi::rule<std::string::iterator, int()> production_;
production_ = omit[*(char_ - "productionYear") >>
lit('"') >> lit(' ') >> lit(':') >> lit(' ')] >> int_;

int year;
auto it = data.begin();

if (boost::spirit::qi::parse(it, data.end(), production_, year))
{
std::cout << "Parse finished with succeded status"<< std::distance(data.begin(), it);
}

Сбой парсера с последней позицией итератора: 0

Кто-нибудь может сказать мне, что я делаю не так?

2

Решение

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ

Делать не сделай это. Используйте анализатор JSON. Есть много. Ваша грамматика хрупкая в разы. (Вы остановитесь на productionYear внутри другого значения, как частичное совпадение в более длинном ключе, как свойство вложенных / родственных объектов, UNICODE экранируется, экранируется. Вы не допустите допустимых пробелов в формате JSON и т. Д.).

Посмотрите здесь, что нужно для разумного разбора JSON в Spirit: https://github.com/sehe/spirit-v2-json/blob/master/json.cpp

*(char_ - "productionYear")

Разбирает любой текст вплоть до (но не включая) productionYear,

Это означает, что следующий символ никогда не совпадает '"' (потому что это 'p').

Прямое исправление

#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;

int main() {
std::string const data = R"({
"cars": [{
"name": "BMW",
"engine": 3.0
},
{
"name": "Citroen",
"engine": 3.6
},
{
"name": "Ferrari",
"engine": 4.2
}],
"productionYear" : 1999
})";

boost::spirit::qi::rule<std::string::const_iterator, int()> production_;
production_ = qi::omit[+(qi::char_ - "productionYear") >> "productionYear\"" >> ' ' >> ':' >> ' '] >> qi::int_;

int year;
auto it = data.begin(), last = data.end();

if (qi::parse(it, last, production_, year)) {
std::cout << "Parsed: " << year << "\n";
} else {
std::cout << "Parsed failed\n";
}

if (it != last)
std::cout << "Remaining input: '" << std::string(it, last) << "'\n";
}

Жить на Колиру

Выход:

Parsed: 1999
Remaining input: '
}'
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]