【问题标题】:Extracting Values from string using spirit parser使用精神解析器从字符串中提取值
【发布时间】:2015-07-09 09:59:03
【问题描述】:

我有以下行 /90pv-RKSJ-UCS2C usecmap

std::string const line = "/90pv-RKSJ-UCS2C usecmap";

auto first = line.begin(), last = line.end();

std::string label, token;
bool ok = qi::phrase_parse(
        first, last, 
        qi::lexeme [ "/" >> +~qi::char_(" ") ] >> ' ' >>  qi::lexeme[+~qi::char_(' ')] , qi::space, label, token);


if (ok)
    std::cout << "Parse success: label='" << label << "', token='" << token << "'\n";
else
    std::cout << "Parse failed\n";

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

我想在标签中90pv-RKSJ-UCS2C和在令牌变量中usecmap。

我提取了 90pv-RKSJ-UCS2C 值,但没有提取 usecmap

【问题讨论】:

    标签: c++ boost boost-spirit boost-spirit-qi


    【解决方案1】:

    使用space 作为船长,你永远无法匹配' '(它被跳过了!)。另见:Boost spirit skipper issues

    所以,要么不要使用船长,要么让船长吃掉它:

    bool ok = qi::phrase_parse(
            first, last, 
            qi::lexeme [ "/" >> +qi::graph ] >> qi::lexeme[+qi::graph], qi::blank, label, token);
    

    注意事项:

    • 我使用 qi::graph 而不是 ~qi::char_(" ") 公式
    • 我用blank_type是因为你说

      我有下面一行

      这意味着不应跳过行尾

    演示

    Live On Coliru

    #include <boost/spirit/include/qi.hpp>
    
    namespace qi = boost::spirit::qi;
    
    int main()
    {
        std::string const line = "/90pv-rksj-ucs2c usecmap";
    
        auto first = line.begin(), last = line.end();
    
        std::string label, token;
        bool ok = qi::phrase_parse(
                first, last, 
                qi::lexeme [ "/" >> +qi::graph ] >> qi::lexeme[+qi::graph], qi::blank, label, token);
    
        if (ok)
            std::cout << "parse success: label='" << label << "', token='" << token << "'\n";
        else
            std::cout << "parse failed\n";
    
        if (first!=last)
            std::cout << "remaining unparsed input: '" << std::string(first, last) << "'\n";
    }
    

    打印:

    parse success: label='90pv-rksj-ucs2c', token='usecmap'
    

    【讨论】:

      【解决方案2】:

      如果你使用的是 C++11,我建议使用正则表达式。

      #include <iostream>
      #include <regex>
      using namespace std;
      int main() {
          regex re("^/([^\\s]*)\\s([^\\s]*)"); // 1st () captures
                                               // 90pv-RKSJ-UCS2C and 2nd () captures usecmap
          smatch sm;
          string s="/90pv-RKSJ-UCS2C usecmap";
          regex_match(s,sm,re);
          for(int i=0;i<sm.size();i++) {
              cout<<sm[i]<<endl;
          }
          string label=sm[1],token=sm[2];
          system("pause");
      }
      

      【讨论】:

        猜你喜欢
        • 2018-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-08
        • 2011-05-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多