使用boost :: spirit :: qi

时间:2015-06-29 06:57:23

标签: c++ boost boost-spirit boost-spirit-qi

我需要使用boost :: spirit :: qi:

解析下面的字符串
  

STR1
  str1_str
  str1_str / str
  str1_str / str / *

即,需要解析由'/'分隔的标识符字符串,如果最后一个符号为'/',那么'*'应该在之后。

我写了下面的代码来完成工作:

#include <boost/spirit/include/qi.hpp>
#include <boost/algorithm/string/join.hpp>

#include <iostream>
#include <string>
#include <vector>

namespace client
{
    namespace qi = boost::spirit::qi;

    template <typename Iterator>
    bool parseName(Iterator first, Iterator last, std::string& name)
    {
        std::vector<std::string> vec;
        char c;
        boost::optional<std::string> o;
        std::string spaces;
        std::string spaces1;
        bool r = qi::phrase_parse(first, last,
            (

                qi::alnum >> *(+qi::alnum | qi::string("_") | (qi::string("/") >> +qi::alnum)) >> -qi::string("/*")

            )
            ,
            qi::blank, c,  vec, o);

        if (first != last) // fail if we did not get a full match
            return false;

        name = c + boost::algorithm::join(vec, "");
        if (o) {
            name += *o;
        }
        return r;
    }
}

int main()
{
    std::string str;
    std::getline(std::cin, str);
    std::string name;
    if (client::parseName(str.begin(), str.end(), name)) {
        std::cout << "parsed:\n";
        std::cout << "name: " << name << std::endl;
    } else {
        std::cout << "not oook\n" ; 
    }
    return 0;
}

我想知道为什么qi::phrase_parse无法将所有匹配项写入一个属性string或至少vector<string>?或者我做错了什么。

如何在不传递charboost::optional<std::string>属性的情

提前致谢!

1 个答案:

答案 0 :(得分:2)

我并不完全清楚你想要达到的目标。

如果我假设我能想到的最简单的事情,那就是我的想法:


protected $namespace = 'App\Http\Controllers';

现在,我已经创建了一个小型测试程序,请注意我以static const qi::rule<Iterator, std::string()> segment = qi::alnum >> *(qi::alnum|qi::char_('_')); std::vector<std::string> segments; bool have_wildcard; bool r = qi::parse( first, last, segment % '/' >> -qi::matches [ "/*" ], segments, have_wildcard); 作为分隔符加入,以便更容易看到结果:

::

<强>演示

<强> Live On Coliru

r &= (first == last); // fail if we did not get a full match

if (r) {
    if (have_wildcard)
        segments.emplace_back("*");
    name = boost::algorithm::join(segments, "::");
}

打印

#include <boost/spirit/include/qi.hpp>
#include <boost/algorithm/string/join.hpp>
#include <iostream>
#include <string>
#include <vector>
namespace client {
    namespace qi = boost::spirit::qi;

    template <typename Iterator>
        bool parseName(Iterator first, Iterator last, std::string& name) {
            static const qi::rule<Iterator, std::string()> segment = qi::alnum >> *(qi::alnum|qi::char_('_'));

            std::vector<std::string> segments;
            bool have_wildcard;

            bool r = qi::parse(
                    first, last, 
                    segment % '/' >> -qi::matches [ "/*" ],
                    segments, 
                    have_wildcard);

            r &= (first == last); // fail if we did not get a full match

            if (r) {
                if (have_wildcard)
                    segments.emplace_back("*");
                name = boost::algorithm::join(segments, "::");
            }

            return r;
        }
}

int main()
{
    //std::string str = "";
    //std::getline(std::cin, str);
    for (std::string const str : {
            "str1", 
            "str1_str", 
            "str1_str/str", 
            "str1_str/str/*", 
        })
    {
        std::string name;
        std::cout << "\n-------------------\ninput: '" << str << "'\n";
        if (client::parseName(str.begin(), str.end(), name)) {
            std::cout << "name: " << name << std::endl;
        } else {
            std::cout << "not oook\n";
        }
    }
}