2

ブーストスピリットを使用して、括弧内にいくつかのデータが続く文字列を抽出したいと思います。関連する文字列は、左括弧からスペースで区切られます。残念ながら、文字列自体にスペースが含まれている可能性があります。末尾のスペースなしで文字列を返す簡潔なソリューションを探しています。

次のコードは、問題を示しています。

#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;
}

その出力は次のとおりです。

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

この単純な文法では、抽出された文字列の後に常にスペースが続きます (これは削除したいのですが)。

これはより大きな文法の一部にすぎないため、ソリューションは Spirit 内で機能するはずです。(したがって、解析後に抽出された文字列をトリミングするのはおそらく不器用です。)

前もって感謝します。

4

1 に答える 1

3

コメントが言ったように、単一のスペースの場合は、それをハードコーディングできます。より柔軟または寛容である必要がある場合:

rawあなたの目的のためにスキッパーを「チート」するためにスキッパーを使用します:

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

これは機能し、印刷されます

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

Coliruでライブを見る

参照用の完全なプログラム:

#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;
}
于 2013-10-25T15:47:39.957 に答える