c++ - Boost spirit解析字符串以前缀开头

标签 c++ string boost-spirit prefix

我目前正在尝试解析字符串,从一些前缀 + 数字开始。 像 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

最佳答案

由于您提供了船长,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/

相关文章:

c++ - 如何在没有其他变量的情况下获得当前位置?

c++ - QCompleter强制双输入

java - 使用正则表达式时消除字符串末尾的尾随空格?

c - 打印 printf 中正数的前导 '+'

c++ - boost spirit 解析引用字符串失败

C++ 工厂模式语法

c++ - 链表删除

php - xss检测这个功能够用吗?

c++11 - 提升平凡语法的编译错误

boost-spirit - 如果使用惰性求值实现三元类型