我需要使用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>
?或者我做错了什么。
如何在不传递char
和boost::optional<std::string>
属性的情
提前致谢!
答案 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";
}
}
}