Вот моя версия с изменениями, помеченными:
#include <boost/spirit/include/qi.hpp>
#include <iostream>
namespace qi = boost::spirit::qi;
int main(int, char**) {
auto txt = qi::lexeme[+(qi::char_("a-zA-Z_"))]; // CHANGE: avoid eating spaces
auto rule = qi::lit("Hello") >> txt % ',' >> "end";
std::string str = "Hello Foo, Moo, Baz end"; // CHANGE: re-introduce spaces
std::string::iterator begin = str.begin();
if (qi::phrase_parse(begin, str.end(), rule, qi::ascii::space)) { // CHANGE: used phrase_parser with a skipper
std::cout << "Match !" << std::endl << "Remainder (should be empty): '"; // CHANGE: show if we parsed the whole string and not just a prefix
std::copy(begin, str.end(), std::ostream_iterator<char>(std::cout));
std::cout << "'" << std::endl;
}
else {
std::cout << "No match :'(" << std::endl;
}
}
Компилируется и работает с GCC 4.4.3 и Boost 1.4something; выход:
Match !
Remainder (should be empty): ''
Используя lexeme
, вы можете избежать условного употребления пробелов, так что txt
соответствует только границе слова. Это дает желаемый результат: поскольку за "Baz"
не стоит запятая, а txt
не использует пробелы, мы никогда не будем случайно потреблять "end"
.
Во всяком случае, я не на 100% уверен, что это то, что вы ищете - в частности, str
пропущены пробелы в качестве иллюстративного примера, или вы как-то вынуждены использовать этот (без пробелов) формат?
Примечание: если вы хотите убедиться, что вы проанализировали всю строку, добавьте проверку, чтобы проверить, если begin == str.end()
. Как уже говорилось, ваш код сообщит о совпадении, даже если был проанализирован только непустой префикс str
.
Обновление: Добавлена суффиксная печать.