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



我有以下行/90 pv-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 failedn";
if (first!=last)
    std::cout << "Remaining unparsed input: '" << std::string(first, last) << "'n";

我想90pv-RKSJ-UCS2C标签usecmap令牌变量

我提取90pv-RKSJ-UCS2C值,但不提取usecmap

如果space为船长,则无法匹配' '(它将被跳过!)。参见:增强精神船长问题

所以,要么不要用跳鱼,要么让跳鱼吃掉它:

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 failedn";
    if (first!=last)
        std::cout << "remaining unparsed input: '" << std::string(first, last) << "'n";
}

打印:

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

如果你正在使用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");
}

最新更新