2017-04-13 19 views
2

我想分析下述JSON並從中提取productionYear值發現了一些字

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 ,它也不是有效的C++。 – cdhowie

回答

2

免責聲明

做到這一點。使用JSON解析器。有很多。你的語法是千差萬別的脆弱。 (你將在productionYear內停止另一個值,作爲長鍵中的部分匹配,作爲嵌套/同級對象的屬性,UNICODE轉義,轉義。您將不允許有效的JSON可選空白等)。

在這裏看到什麼需要精神來解析JSON,在合理的範圍: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"; 
} 

Live On Coliru

輸出:

Parsed: 1999 
Remaining input: ' 
    }'