简体   繁体   English

使用精神解析器从字符串中提取值

[英]Extracting Values from string using spirit parser

i have following line /90pv-RKSJ-UCS2C usecmap 我有以下行/ 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";

I want to 90pv-RKSJ-UCS2C in label and usecmap in token variable. 我想在标签中使用90pv-RKSJ-UCS2C并在令牌变量中使用usecmap

I extract 90pv-RKSJ-UCS2C value but not usecmap 我提取90pv-RKSJ-UCS2C值但不提取usecmap

With space the skipper, you cannot ever match ' ' (it is skipped!). 随着船长的space ,你不能匹配' ' (它被跳过!)。 See also: Boost spirit skipper issues 另见: 提升精神船长问题

So, either don't use a skipper, or allow the skipper to eat it: 所以,要么不使用船长,要么让船长吃掉它:

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

Notes: 笔记:

  • I used qi::graph instead of the ~qi::char_(" ") formulation 我使用qi::graph而不是~qi::char_(" ")公式
  • I used blank_type because you said 因为你说过,我使用了blank_type

    i have following line 我有以下行

    Which implies that line-ends should not be skipped 这意味着不应该跳过行尾

Demo 演示

Live On Coliru 住在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";
}

Prints: 打印:

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

If you are using C++11, I suggest using regular expression. 如果您使用的是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");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM