我有以下字符串:
regname : temp1
regname : temp2
regname : temp3
regname : temp4
value at index : 0 is : temp1
value at index : 1 is : temp2
value at index : 2 is : temp3
value at index : 3 is : temp4
我想解析它并存储/提取括号中的%%DocumentNeededResources: CMap (90pv-RKSJ-UCS2C)
字符串。
我的规则如下:
90pv-RKSJ-UCS2C
答案 0 :(得分:1)
看起来你认为船长是拆分分隔符。它完全相反(Boost spirit skipper issues)。
在这种罕见的情况下,我认为我更喜欢正则表达式。但是,既然你问过这里的精神:
<强> Live On Coliru 强>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
int main() {
std::string const line = "%%DocumentNeededResources: CMap (90pv-RKSJ-UCS2C)";
auto first = line.begin(), last = line.end();
std::string label, token;
bool ok = qi::phrase_parse(
first, last,
qi::lexeme [ "%%" >> +~qi::char_(":") ] >> ':' >> qi::lexeme["CMap"] >> '(' >> qi::lexeme[+~qi::char_(')')] >> ')',
qi::space,
label, token);
if (ok)
std::cout << "Parse success: label='" << label << "', token='" << token << "'\n";
else
std::cout << "Parse failed\n";
if (first!=last)
std::cout << "Remaining unparsed input: '" << std::string(first, last) << "'\n";
}
打印
Parse success: label='DocumentNeededResources', token='90pv-RKSJ-UCS2C'
答案 1 :(得分:1)
好吧,假设我们给出了以下using
和别名命名空间指令:
using namespace boost::spirit::qi;
namespace phx = boost::phoenix;
给出字符串:
std::string strLinesRecur = "%%DocumentNeededResources: CMap (90pv-RKSJ-UCS2C)";
我们希望提取&#34;代码&#34;在括号内res
:
std::string res;
执行此操作的一种方法是使用boost::phoenix::ref
作为语义操作。
因此给出了一个代码语法:
using boost::spirit::ascii::alnum;
auto code = copy(+(alnum | char_('-')));
(这与正则表达式[a-zA-Z\-]
中的内容一致)
我们可以为整个字符串创建自己的语法:
using boost::spirit::ascii::alpha;
auto grammar = copy(
(char_('%') >> char_('%') >> +alpha >> char_(':'))
>> +alpha >> char_('(') >> as_string[lexeme[code]][phx::ref(res) = _1] >> char_(')'));
分析以两个%
开头的任何内容,后跟一些字母字符和:
,然后是一些&#34;代码&#34;在括号内。
关键是as_string[lexeme[code]][phx::ref(res) = _1]
。如果我们将其分解:lexeme[code]
只是将解析后的code
视为原子单位,as_string
&#34;返回&#34;结果为std::string
(与std::vector<char>
相对)和[phx::ref(res) = _1]
使用语义操作将已解析的字符串存储到res
中(_1
是第一个占位符在那个语法中匹配。)
在这种情况下,以下调用会跳过空格:
using boost::spirit::ascii::blank;
phrase_parse(begin(strLinesRecur), end(strLinesRecur), grammar, blank);
这当然只是一个符合字符串的语法示例。
注意:copy
是指qi::copy
,它是一种能够存储对象code
和{{1}中的语法片段的方法}。没有它,grammar
的使用将失败(可能存在分段错误)。