Boost Spirit语法用于识别从一行到向量的一系列数字

Boost Spirit syntax for recognising series of numbers from a line into vector?

本文关键字:一行 向量 数字 一系列 语法 Spirit 用于 识别 Boost      更新时间:2023-10-16

我有一个字符串,有这样的味道:

  SCALE FACTORS      16.      0.0     0.0     0.0     0.0      .

  SCALE FACTORS      30.       .       .       .       .       .

  SCALE FACTORS     256.      10.0     20.0     30.0    .

所以,几个末尾有点的数字,只有点和空格。这是一些历史数据格式,我有太多的文件需要手动调整,以使其更易于阅读。

行首始终为"SCALE FACTORS",可作为固定模板"读取"。

我需要一个boost spirit表达式来帮助我在向量中识别这个字符串。单独的点必须被丢弃(或者至少被读为0)。数字必须以vector形式存储。

一行的有效位数在1到数之间(不固定)。

我的主要问题是,如何在一个向量中存储一串数字。原则上,我可以在没有Boost Spirit的帮助下移除杂散点。

使用blank_type船长,您可以

    start = line % eol;
    line  = lit("SCALE") >> "FACTORS" >> *(double_|'.')

这将导致'.'项为零:

Parsed 3 lines
[SCALE FACTORS] 16 0 0 0 0 0 
[SCALE FACTORS] 30 0 0 0 0 0 
[SCALE FACTORS] 256 10 20 30 0 
Remaining input: '
'

查看Live On Coliru

#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/format.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <cstdint>
namespace qi  = boost::spirit::qi;
namespace phx = boost::phoenix;
typedef std::vector<double> line_t;
typedef std::vector<line_t> lines_t;
template <typename Iterator>
struct sfparser : public qi::grammar<Iterator, lines_t(), qi::blank_type>
{
    sfparser () : sfparser::base_type(start)
    {
        using namespace qi;
        start = line % eol;
        line  = lit("SCALE") >> "FACTORS" >> *(double_|'.');
    }
  private:
    qi::rule<Iterator, lines_t(), qi::blank_type> start;
    qi::rule<Iterator, line_t(), qi::blank_type > line;
};
int main()
{
    std::string const input = " SCALE FACTORS      16.      0.0     0.0     0.0     0.0      .n"
        "SCALE FACTORS      30.       .       .       .       .       .n"
        "  SCALE FACTORS     256.      10.0     20.0     30.0    .n";
    std::string::const_iterator f = input.begin();
    std::string::const_iterator l = input.end();
    sfparser<std::string::const_iterator> grammar;
    lines_t data;
    if (qi::phrase_parse (f, l, grammar, qi::blank, data))
    {
        std::cout << "Parsed " << data.size() << " linesn";
        for (auto& line : data)
        {
            std::cout << "[SCALE FACTORS] ";
            for (auto d : line)
                std::cout << d << " ";
            std::cout << "n";
        }
    }
    else
    {
        std::cout << "Failedn";
    }
    if (f!=l)
        std::cout << "Remaining input: '" << std::string(f,l) << "'n";
}