【问题标题】:Boost spirit parsing提升精神解析
【发布时间】:2011-12-08 10:54:11
【问题描述】:

我正在尝试获取一个字符串,然后从中检索所需的元素。目前,我似乎无法找到一种方法,因为输入字符串会不时更改,尽管元素不会。

到目前为止,我的代码如下。我要做的是在解析时从字符串中提取'.V/'

到目前为止,我的代码可以工作,但我需要它更通用,因为输入的字符串中有很多元素

  • .V/ER/12/FRG/45S/16JAN
    .E/45/SHAM/CAMP/2 
    

    我需要检索.V/.E/

 

std::vector<std::string>elements;
std::string input = ".V/ER/12/FRG/45S/16JAN ";

bool result = qi::parse(input.begin(),input.end(),
        *(*(qi::char_ - " /ER/12/FRG/45S/16JAN\n") >> " /ER/12/FRG/45S/16JAN\n"),
        elements
        );  

【问题讨论】:

    标签: c++ boost boost-spirit


    【解决方案1】:

    我真的建议对这项工作使用正则表达式(boost regex 或 std::regex)。

    正则表达式可能看起来像

    std::regex re("^(\\.[EV]/).*?$"); // the first submatch is the part you are looking for
    

    这里有一点精神,以防你真的需要它:

    #include <boost/spirit/include/qi.hpp>
    namespace qi = boost::spirit::qi;
    
    typedef std::string::const_iterator It;
    
    int main()
    {
        std::vector<std::string>elements;
        std::string input = 
            ".V/ER/12/FRG/45S/16JAN\n"
            ".E/45/SHAM/CAMP/2";
    
        It first(input.begin()), last(input.end());
    
        bool ok = qi::parse(first, last,
                (
                  '.' > qi::char_("EV") > '/' 
                     >> qi::omit [ *(qi::char_ - qi::eol) ] 
                ) % qi::eol,
                elements);
    
        if (ok)
        {
            for (int i=0; i<elements.size(); ++i)
                std::cout << elements[i] << std::endl;
        } else
        {
            std::cerr << "Parse failed at '" << std::string(first, last) << std::endl;
        }
    
    }
    

    这将输出

    V
    E
    

    如果你想在那里显示'.E/',有很多方法,例如

    bool ok = qi::parse(first, last,
            (
              (qi::char_('.') > qi::char_("EV") > qi::char_('/' )
                 >> qi::omit [ *(qi::char_ - qi::eol) ] )
            ) % qi::eol,
            elements);
    

    输出:

    .V/
    .E/
    

    奖金

    显示如何包含线的“尾部”,可能存储到地图中:

    #include <map>
    #include <boost/spirit/include/qi.hpp>
    #include <boost/fusion/adapted/std_pair.hpp>
    namespace qi = boost::spirit::qi;
    
    typedef std::string::const_iterator It;
    
    int main()
    {
        typedef std::map<std::string, std::string> result_t;
        // or use a list to allow duplicate keys:
        // typedef std::list<std::pair<std::string, std::string> > result_t;
        result_t mappings;
    
        std::string input = 
            ".V/ER/12/FRG/45S/16JAN\n"
            ".E/45/SHAM/CAMP/2";
    
        It first(input.begin()), last(input.end());
    
        bool ok = qi::parse(first, last, (
                      qi::raw [ '.' > qi::char_("EV") > '/' ]
                    > qi::raw [ *(qi::char_ - qi::eol) ]
                ) % qi::eol,
                mappings);
    
        if (ok)
        {
            for (result_t::const_iterator it=mappings.begin();
                 it!=mappings.end(); ++it)
            {
                std::cout << it->first << " maps to " << it->second << std::endl;
            }
        } else
        {
            std::cerr << "Parse failed at '" << std::string(first, last) << std::endl;
        }
    
    }
    

    会输出

    .E/ maps to 45/SHAM/CAMP/2
    .V/ maps to ER/12/FRG/45S/16JAN
    

    【讨论】:

    • 添加了额外的材料 - 午休:)
    • ahhhhh 好的,我明白了,是的,那应该没问题,感谢您的帮助 mn :) 谢谢!
    • @ShamariCampbell:干杯。如果证明有帮助,请记得点赞/接受答案 (meta.stackexchange.com/questions/5234/…)
    • Qucik 解析问题有一种方法如何解析但不要停止解析,即如果您寻找“E”“V”但“E”“V”并不相邻会导致解析失败有没有办法不导致解析失败?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多