我目前正在尝试解析字符串,从一些前缀 + 数字开始。
像 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
这样的标记。
有什么建议吗?
谢谢!
最佳答案
由于您提供了船长,sequence parser以及加解析器(和其他一些)它用于原始解析器匹配之间,并且由于 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+
。
关于c++ - Boost spirit解析字符串以前缀开头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58954632/