How to extract trimmed text using Boost Spirit?

元气小坏坏 提交于 2019-12-11 01:31:27

问题


Using boost spirit, I'd like to extract a string that is followed by some data in parentheses. The relevant string is separated by a space from the opening parenthesis. Unfortunately, the string itself may contain spaces. I'm looking for a concise solution that returns the string without a trailing space.

The following code illustrates the problem:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <string>
#include <iostream>

namespace qi = boost::spirit::qi;
using std::string;
using std::cout;
using std::endl;

void
test_input(const string &input)
{
    string::const_iterator b = input.begin();
    string::const_iterator e = input.end();
    string parsed;
    bool const r = qi::parse(b, e,
        *(qi::char_ - qi::char_("(")) >> qi::lit("(Spirit)"),
            parsed
    );
    if(r) {
        cout << "PASSED:" << endl;
    } else {
        cout << "FAILED:" << endl;
    }
    cout << "  Parsed: \"" << parsed << "\"" << endl;
    cout << "  Rest: \"" << string(b, e) << "\"" << endl;
}

int main()
{
    test_input("Fine (Spirit)");
    test_input("Hello, World (Spirit)");

    return 0;
}

Its output is:

PASSED:
  Parsed: "Fine "
  Rest: ""
PASSED:
  Parsed: "Hello, World "
  Rest: ""

With this simple grammar, the extracted string is always followed by a space (that I 'd like to eliminate).

The solution should work within Spirit since this is only part of a larger grammar. (Thus, it would probably be clumsy to trim the extracted strings after parsing.)

Thank you in advance.


回答1:


Like the comment said, in the case of a single space, you can just hard code it. If you need to be more flexible or tolerant:

I'd use a skipper with raw to "cheat" the skipper for your purposes:

bool const r = qi::phrase_parse(b, e,
    qi::raw [ *(qi::char_ - qi::char_("(")) ] >> qi::lit("(Spirit)"),
    qi::space,
    parsed
);

This works, and prints

PASSED:
  Parsed: "Fine"
  Rest: ""
PASSED:
  Parsed: "Hello, World"
  Rest: ""

See it Live on Coliru

Full program for reference:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <string>
#include <iostream>

namespace qi = boost::spirit::qi;
using std::string;
using std::cout;
using std::endl;

void
test_input(const string &input)
{
    string::const_iterator b = input.begin();
    string::const_iterator e = input.end();
    string parsed;
    bool const r = qi::phrase_parse(b, e,
        qi::raw [ *(qi::char_ - qi::char_("(")) ] >> qi::lit("(Spirit)"),
        qi::space,
        parsed
    );
    if(r) {
        cout << "PASSED:" << endl;
    } else {
        cout << "FAILED:" << endl;
    }
    cout << "  Parsed: \"" << parsed << "\"" << endl;
    cout << "  Rest: \"" << string(b, e) << "\"" << endl;
}

int main()
{
    test_input("Fine (Spirit)");
    test_input("Hello, World (Spirit)");

    return 0;
}


来源:https://stackoverflow.com/questions/19591694/how-to-extract-trimmed-text-using-boost-spirit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!