【发布时间】:2014-12-25 10:42:45
【问题描述】:
我想用正则表达式来计算下面的表达式。
Execute stmtname
and
Execute stmtname using @a,@b;
我想提取 stmtname 和变量列表。 我尝试了以下方法。
^execute[\s\t]+(\w+)[\s\t]+(using[\s\t]*(.+))?
但只能解析第二条语句。 有没有人帮我解决这个问题。
【问题讨论】:
我想用正则表达式来计算下面的表达式。
Execute stmtname
and
Execute stmtname using @a,@b;
我想提取 stmtname 和变量列表。 我尝试了以下方法。
^execute[\s\t]+(\w+)[\s\t]+(using[\s\t]*(.+))?
但只能解析第二条语句。 有没有人帮我解决这个问题。
【问题讨论】:
我可能不会尝试用正则表达式“解析”语法。既然您已经在使用 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
#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";
}
}
【讨论】: