现在我有这个提升::精神模式:
str_p("url(") >> !( str_p("'") | str_p("\"") ) >> ("#") >>
((+alnum_p)[assign_a(o_rPaintUri)] >>
!( str_p("'") | str_p("\"") ) >> str_p(")")
这样可以解析url(#myRadialGradient)
之类的内容,但是如果有url(#my-RadialGradient4)
这样的连字符则不起作用。
我尝试过像(+alnum_p | '-')[assign_a(o_rPaintUri)]
这样的东西,但它没有用。
任何人都有提示如何做到这一点?
由于
答案 0 :(得分:2)
那是精神经典(又名.v1.x)。
PS。 没有任何线索,但您可以尝试(+(alnum_p | ch_p('-')))
而不是(+alnum_p | '-')
你应该进入本世纪,并使用Spirit V2(自取代v1以来大约十年):
<强> Live On Coliru 强>
#include <boost/spirit/include/qi.hpp>
int main() {
for (std::string const sample : {
"url(#myRadialGradient)",
"url(#my-RadialGradient4)",
"url('#my-RadialGradient4')",
"url(\"#my-RadialGradient4\")",
})
{
std::cout << " -- parsing '" << sample << "'\n";
std::string o_rPaintUri;
bool ok;
{
using namespace boost::spirit::qi;
ok = parse(sample.begin(), sample.end(),
"url(" >> -char_("'\"") >> "#" >> +(alnum|char_('-')) >> -char_("'\"") >> ")",
o_rPaintUri);
}
if (ok)
std::cout << "Parsed: '" << o_rPaintUri << "'\n";
else
std::cout << "Parse failed\n";
}
}
打印
-- parsing 'url(#myRadialGradient)'
Parsed: 'myRadialGradient'
-- parsing 'url(#my-RadialGradient4)'
Parsed: 'my-RadialGradient4'
-- parsing 'url('#my-RadialGradient4')'
Parsed: ''my-RadialGradient4''
-- parsing 'url("#my-RadialGradient4")'
Parsed: '"my-RadialGradient4"'
相同,但将qi
替换为x3
。我建议做些改进:
<强> Live On Coliru 强>
#include <boost/spirit/home/x3.hpp>
#include <boost/exception/all.hpp>
#include <iostream>
namespace x3 = boost::spirit::x3;
int main() {
for (std::string const sample : {
"url(#myRadialGradient)",
"url(#my-RadialGradient4)",
"url('#my-RadialGradient4')",
"url(\"#my-RadialGradient4\")",
// extra
"url('#my-RadialGradient4\")",
"url('#my-Radial_Gradient4')",
"url('#my-Radial_Gradient4'",
"url(oops)",
"url('oops')",
"url(\"oops\")",
"oops",
})
{
std::cout << " -- parsing " << sample << "\n";
std::string o_rPaintUri;
bool ok = false;
try {
using namespace x3;
auto q = [](auto quote) { return quote > as_parser('#') > *(char_ - quote) > quote; };
auto u = rule<struct url, std::string> { "#anchor|'#anchor'|\"#anchor\"" } // FOR ERROR INFO ONLY
= q("'") | q('"') | '#' >> *~char_(')');
ok = parse(sample.begin(), sample.end(), eps > "url(" > u > ")", o_rPaintUri);
if (ok)
std::cout << "Parsed: '" << o_rPaintUri << "'\n";
else
std::cout << "Parse failed\n";
} catch (x3::expectation_failure<std::string::const_iterator> const& e) {
std::cout << " Error: '" << std::string(e.where(), sample.end()) << "', expecting " << e.which() << "\n";
}
}
}
打印
-- parsing url(#myRadialGradient)
Parsed: 'myRadialGradient'
-- parsing url(#my-RadialGradient4)
Parsed: 'my-RadialGradient4'
-- parsing url('#my-RadialGradient4')
Parsed: 'my-RadialGradient4'
-- parsing url("#my-RadialGradient4")
Parsed: 'my-RadialGradient4'
-- parsing url('#my-RadialGradient4")
Error: '', expecting "'"
-- parsing url('#my-Radial_Gradient4')
Parsed: 'my-Radial_Gradient4'
-- parsing url('#my-Radial_Gradient4'
Error: '', expecting ')'
-- parsing url(oops)
Error: 'oops)', expecting #anchor|'#anchor'|"#anchor"
-- parsing url('oops')
Error: 'oops')', expecting '#'
-- parsing url("oops")
Error: 'oops")', expecting '#'
-- parsing oops
Error: 'oops', expecting "url("