我有以下字符串
GOOSE BAY LATITUDE 53.27 LONGITUDE 299.60 ALTITUDE 46 M
我需要使用Boost精神解析变量。
目前我的代码如下:
qi::rule < string::const_iterator, std::string(), asc::space_type> any_string;
any_string %= as_string [lexeme[+(asc::char_ - asc::space)]];
r = phrase_parse(first, last,
(any_string[ph::ref(station) = _1] >> "LATITUDE" >>
double_[ph::ref(lat) = _1] >> "LONGITUDE" >> double_[ph::ref(lon) = _1] >>
"ALTITUDE" >> double_[ph::ref(alt) = _1] >> "M"), asc::space);
工作正常(即商店 电台 , lat , lon , alt 变量)如果在“LATITUDE”之前,我只有一个字。
然而,我还需要在“LATITUDE”之前存储变量 station ,如果它是一个或几个(不仅仅是两个,如例子)单词。但它不能消耗任何后续的“LATITUDE”字,所以纬度等仍然是他们自己的变量。请帮助我找出正确的Boost Spirit表达式以识别 station 在行中看到的所有内容,包含的空格,最多为特殊单词(上例中的LATITUDE) )。
答案 0 :(得分:4)
注意:
asc::graph
相当于asc::char_ - asc::space
。 lexeme
是多余的(另请参阅Boost spirit skipper issues)
qi::rule<It> any_string = +qi::graph_;
在第一个字段中的每个字符处断言第一个关键字的否定匹配:
+(qi::char_ - "LATITUDE")
您可以传递对phrase_parse
API的引用,这样您就可以不进行语义操作(另请参阅Boost Spirit: "Semantic actions are evil"?):
bool r = qi::phrase_parse(first, last,
( qi::raw [ +(qi::char_ - "LATITUDE") ] >> "LATITUDE" >>
qi::double_ >> "LONGITUDE" >>
qi::double_ >> "ALTITUDE" >>
qi::double_ >> "M"),
asc::space,
name, lat, lon, alt);
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
namespace asc= boost::spirit::ascii;
int main()
{
typedef std::string::const_iterator It;
std::string const input("GOOSE BAY LATITUDE 53.27 LONGITUDE 299.60 ALTITUDE 46 M");
std::string name;
double lat, lon, alt;
It first(input.begin()), last(input.end());
bool r = qi::phrase_parse(first, last,
(qi::raw [ +(qi::char_ - "LATITUDE") ] >> "LATITUDE" >>
qi::double_ >> "LONGITUDE" >>
qi::double_ >> "ALTITUDE" >>
qi::double_ >> "M"),
asc::space,
name, lat, lon, alt);
if (r)
std::cout << "Parsed: '" << name << "' lat:" << lat << " lon:" << lon << " alt:" << alt << "\n";
else
std::cout << "Failed\n";
if (first != last)
std::cout << "Remaining input: '" << std::string(first, last) << "'\n";
}