Boost Spirit解析字符串以前缀开头
Posted
技术标签:
【中文标题】Boost Spirit解析字符串以前缀开头【英文标题】:Boost spirit parse string starts with a prefix 【发布时间】:2019-11-20 12:42:28 【问题描述】:我目前正在尝试解析字符串,从一些前缀 + 数字开始。
喜欢abc_.+ \d+
。但是有一些大问题。
这是一个测试代码
#define BOOST_SPIRIT_DEBUG
#include <iostream>
#include <vector>
#include <string>
#include <iterator>
#include <iomanip>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/phoenix/phoenix.hpp>
namespace qi = boost::spirit::qi;
struct S
std::string s;
int n = 0;
;
BOOST_FUSION_ADAPT_STRUCT(S, s, n)
struct parser : qi::grammar<std::string::const_iterator, S(), qi::ascii::space_type>
typedef std::string::const_iterator Iterator;
qi::rule<Iterator, S(), qi::ascii::space_type> start;
qi::rule<Iterator, std::string(), qi::ascii::space_type> abc;
parser() : parser::base_type(start)
abc = qi::raw[ "abc_" >> +(qi::alnum)];
//abc = qi::raw[ "abc_" >> +(qi::alpha)];
start %= abc >> qi::int_;
BOOST_SPIRIT_DEBUG_NODES( (start)(abc))
;
int main()
using boost::spirit::ascii::space;
parser g;
for(std::string str : "abc 1", "abc_ 1", "abc_aaa 1", "abc_555 1", "cba_aaa 1")
std::cout << str << " - ";
std::string::const_iterator iter = str.begin();
std::string::const_iterator end = str.end();
S s;
bool r = phrase_parse(iter, end, g, space, s);
if(r)
std::cout << "Ok";
else
std::cout << "fail";
std::cout << std::endl;
由于某种原因,qi::alnum 也会占用空间:
abc_aaa 1 - <start>
<try>abc_aaa 1</try>
<abc>
<try>abc_aaa 1</try>
<success></success>
<attributes>[[a, b, c, _, a, a, a, , 1]]</attributes>
</abc>
<fail/>
</start>
fail
如果我把它改成 qi::alpha
abc_aaa 1 - <start>
<try>abc_aaa 1</try>
<abc>
<try>abc_aaa 1</try>
<success>1</success>
<attributes>[[a, b, c, _, a, a, a, ]]</attributes>
</abc>
<success></success>
<attributes>[[[a, b, c, _, a, a, a, ], 1]]</attributes>
</start>
Ok
工作正常,但无法解析像 abc_123
这样的标记。
有什么建议吗?
谢谢!
Try it on Coliru
【问题讨论】:
另见***.com/questions/17072987/… 【参考方案1】:由于您提供了一个船长,sequence parser 以及 plus 解析器(和其他一些)它在原始解析器匹配之间使用,因此 abc
解析器匹配 abc_(\s*[0-9a-zA-Z])+
。
对于您的情况,有一个 lexeme
指令,它提供了一种机制来禁用不需要的跳过。像abc = qi::raw[qi::lexeme["abc_" >> +qi::alnum]]
一样使用它会匹配abc_[0-9a-zA-Z]+
,整个语法会匹配abc_[0-9a-zA-Z]+\s*\d+
。
【讨论】:
谢谢尼基塔!abc = qi::raw[qi::lexeme["abc_" >> +qi::alnum]]
完成了这项工作。以上是关于Boost Spirit解析字符串以前缀开头的主要内容,如果未能解决你的问题,请参考以下文章
使用 boost Spirit 解析带有二进制信封的文本文件
防止 Boost Spirit Symbol 解析器过早接受关键字