我目前正在尝试解析如下格式化的文本文件:
[value1(double),value2(double];[value1(double),value2(double];...;[value1(double),value2(double]\n
[value1(double),value2(double];[value1(double),value2(double];...;[value1(double),value2(double]\n
etc...
此文件是传感器所做测量的结果:每个括号 - thingy表示传感器值的间隔,每个不同的线代表一个度量。
问题是,我们有时关掉某些传感器,所以文件格式不一样,所以我真的不知道如何做一般的“通用”解析器,不应该考虑数量接通的传感器。当然,我不知道是否清楚,这个数量的值与文件不同。我的意思是,在同一个文件中,值的数量显然是不变的。因此,如果我关闭每个传感器而不是一个传感器,我会有这样的事情:
[value1(double),value2(double]\n
[value1(double),value2(double]\n
etc...
输出格式为:
LINE 1:
x1min: ... (first value of the first bracket-couple)
x1max: ... (second value of the second bracket-couple)
x2min: ...
x2max: ...
etc...
LINE 2:
same here
ETC
enter code here
非常感谢一些帮助。
祝你有个愉快的一天,非常感谢你。
PS:非常抱歉我的英语不好
答案 0 :(得分:1)
阅读一行:
[value1,value2];[value1,value2];[value1,value2];.........
处理这一行:
Till the end of line is met do:
For all chars from '[' to ']', read the 2 values.
Store val1 and val2
重复此操作直到文件结束。
答案 1 :(得分:0)
你可以读取第一行,计算左括号'['的数量,然后从中设置一个固定长度的解析器。
答案 2 :(得分:0)
Boost.Spirit提供了一个完整的解析工具:这里有一些代码可以使用并适应您的特定问题:
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <vector>
#include <string>
#include <iostream>
namespace client
{
using namespace std;
typedef pair<string, double> t_named_num;
typedef vector<t_named_num> t_named_numbers;
typedef vector<t_named_numbers> t_records;
namespace qi = boost::spirit::qi;
template <typename Iterator>
struct parse_records : qi::grammar<Iterator, t_records()>
{
parse_records() : parse_records::base_type(records)
{
name = qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9");
named_num = name >> '(' >> qi::double_ >> ')' ;
named_numbers = '[' >> (named_num % ',') >> ']' ;
records = named_numbers % ';' ;
}
qi::rule<Iterator, string()> name;
qi::rule<Iterator, t_named_num()> named_num;
qi::rule<Iterator, t_named_numbers()> named_numbers;
qi::rule<Iterator, t_records()> records;
};
}
int main(int argc, char *argv[])
{
using namespace std;
using namespace client;
string s("[a(1),b(2),c(3)];[u(31.5),v(32),z(-23)]");
string::iterator i = s.begin(), e = s.end();
parse_records<string::iterator> p;
t_records c;
if (boost::spirit::qi::parse(i, e, p, c))
{
for (t_records::iterator r = c.begin(); r != c.end(); ++r)
{
cout << "record" << endl;
for (t_named_numbers::iterator n = r->begin(); n != r->end(); ++n)
cout << n->first << ':' << n->second << endl;
}
if (i == e)
cout << "ok" << endl;
else
cout << "ko" << endl;
}
else
cout << "??" << endl;
}
计划的输出:
record
a:1
b:2
c:3
record
u:31.5
v:32
z:-23
ok
我必须说它不易使用,但实际上非常强大。 HTH