【问题标题】:Regular expression in boost to extract informationboost中的正则表达式以提取信息
【发布时间】:2014-12-25 10:42:45
【问题描述】:

我想用正则表达式来计算下面的表达式。

Execute stmtname
and
Execute stmtname using @a,@b;

我想提取 stmtname 和变量列表。 我尝试了以下方法。

^execute[\s\t]+(\w+)[\s\t]+(using[\s\t]*(.+))?

但只能解析第二条语句。 有没有人帮我解决这个问题。

【问题讨论】:

    标签: c++ regex parsing boost


    【解决方案1】:

    我可能不会尝试用正则表达式“解析”语法。既然您已经在使用 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";
        }
    }
    

    【讨论】:

    • 感谢您分享使用 boost spirit 的想法。我正在考虑使用这个概念,所以研究这个概念。再次感谢分享运行良好的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-18
    相关资源
    最近更新 更多