c++ - boost中的正则表达式提取信息

标签 c++ regex parsing boost

我想使用正则表达式来处理以下表达式。

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
);

大部分的复杂性只是因为我试图对

  • 分隔的标识符 token (以便例如 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";
    }
}

关于c++ - boost中的正则表达式提取信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27646485/

相关文章:

c++ - 如何使用 Windows x64 记录堆栈帧

java - 尝试执行正则表达式时可能出现反斜杠转义问题

Javascript相同的正则表达式返回不同的结果

Javascript正则表达式正在对文字括号进行分组?

c++ - 使用 Open Cascade 读取步骤文件

c++ - 未解析的外部符号 PriorityQueue

c++ - 在 C++ 中计算家庭作业的闰年?

java - 如何从 SOAP 响应中获取单个元素的值? ( java )

c - 如何从字节可寻址数组中解析出 n 位元素

ruby - 在 Nokogiri 中,如何找到文档中某个节点之前的所有节点?