提升精神解析

时间:2011-12-08 10:54:11

标签: c++ boost boost-spirit

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

到目前为止,我的代码如下。我想要做的是在解析时从字符串中提取'.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
        );  

1 个答案:

答案 0 :(得分:3)

我真的建议使用正则表达式(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/

加成

显示如何包含该行的“尾部”,可能存储到map:

#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