我想使用正则表达式来表达以下表达式。
Execute stmtname
and
Execute stmtname using @a,@b;
我想提取stmtname和变量列表。 我尝试了以下内容。
^execute[\s\t]+(\w+)[\s\t]+(using[\s\t]*(.+))?
但只能解析第二个语句。 有人帮我解决这个问题。
答案 0 :(得分:3)
我可能不会尝试用正则表达式“解析”语法。既然你已经在使用Boost,为什么不用Boost Spirit冒险进入解析器生成器国家?
std::string statement_name;
std::vector<std::string> parameters;
bool ok = qi::phrase_parse(
first, last,
qi::no_case[
sr::distinct(qi::graph) ["execute"]
>> ident_
>> -(sr::distinct(qi::graph) ["using"] >>
('@' >> ident_) % ','
)
>> -qi::lit(';') >> qi::eoi
],
qi::space,
statement_name,
parameters
);
大部分的复杂性只是因为我试图非常细致
execute_only
不会解析为execute _only
),并且;
(您的示例在这方面存在冲突)测试程序打印:
-----------------------------------------
Parsing 'Execute no_parameter_statement'
Parse success
statement_name: no_parameter_statement
0 parameters:
-----------------------------------------
Parsing 'Execute stmtname using @a,@b;'
Parse success
statement_name: stmtname
2 parameters:
@a
@b
<强> Live On Coliru 强>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/repository/include/qi_distinct.hpp>
namespace qi = boost::spirit::qi;
namespace sr = boost::spirit::repository::qi;
typedef std::string::const_iterator It;
qi::rule<It, std::string()> ident_ = sr::distinct(qi::char_("a-z0-9_")) [ qi::alpha >> *(qi::char_("a-z0-9_")) ];
int main() {
for(std::string const input : {
"Execute no_parameter_statement",
"Execute stmtname using @a,@b;"
})
{
std::cout << "-----------------------------------------\n";
std::cout << "Parsing '" << input << "'\n";
std::string statement_name;
std::vector<std::string> parameters;
auto f(input.begin()), l(input.end());
bool ok = qi::phrase_parse(f,l,qi::no_case[
sr::distinct(qi::graph) ["execute"]
>> ident_
>> -(sr::distinct(qi::graph) ["using"] >>
('@' >> ident_) % ','
)
>> -qi::lit(';') >> qi::eoi
],
qi::space,
statement_name,
parameters
);
if (ok) {
std::cout << "Parse success\n";
std::cout << "statement_name: " << statement_name << "\n";
std::cout << parameters.size() << " parameters:\n";
for(auto const& p : parameters)
std::cout << "\t@" << p << "\n";
} else {
std::cout << "Parse failed\n";
}
if (f!=l)
std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
}
}