Как извлечь обрезанный текст с помощью Boost Spirit?

Используя повышение духа, я хотел бы извлечь строку, за которой следуют некоторые данные в скобках. Соответствующая строка отделяется пробелом от открывающей скобки. К сожалению, сама строка может содержать пробелы. Я ищу краткое решение, которое возвращает строку без завершающего пробела.

Следующий код иллюстрирует проблему:

#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: ""

С помощью этой простой грамматики за извлеченной строкой всегда следует пробел (который я хотел бы исключить).

Решение должно работать в Духе, так как это только часть большой грамматики. (Таким образом, вероятно, будет неуклюже обрезать извлеченные строки после анализа.)

Заранее спасибо.

2

Решение

Как сказано в комментарии, в случае одного пробела вы можете просто жестко его кодировать. Если вам нужно быть более гибкий или же терпимый:

Я бы использовал шкипер с 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: ""

Видеть это Жить на Колиру

Полная программа для справки:

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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]