我有数千行输入,每行包含3个整数和一个逗号,并且看起来像这样:
5 6 10,
8 9 45,
.....
如何创建仅解析输入的某个部分的语法,例如前100行或1000行到1200行,并忽略其余部分。
我的语法目前看起来像这样:
qi::int_ >> qi::int_ >> qi::int_ >> qi::lit(",");
但显然它解析了整个输入。
答案 0 :(得分:4)
你可以找到有趣的点并在那里解析100行。
关于如何从精神中跳过100行的草图:
<强> Live On Coliru 强>
#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/std_tuple.hpp>
#include <tuple>
namespace qi = boost::spirit::qi;
int main() {
using It = boost::spirit::istream_iterator;
using Tup = std::tuple<int, int, int>;
It f(std::cin >> std::noskipws), l;
std::vector<Tup> data;
using namespace qi;
if (phrase_parse(f, l,
omit [ repeat(100) [ *(char_ - eol) >> eol ] ] >> // omit 100 lines
repeat(10) [ int_ >> int_ >> int_ >> ',' >> eol ], // parse 10 3-tuples
blank, data))
{
int line = 100;
for(auto tup : data)
std::cout << ++line << "\t" << boost::fusion::as_vector(tup) << "\n";
}
}
使用
等随机输入进行测试时od -Anone -t d2 /dev/urandom -w6 | sed 's/$/,/g' | head -200 | tee log | ./test
echo ============== VERIFY WITH sed:
nl log | sed -n '101,110p'
它会打印预期的内容,例如:
101 (15400 5215 -20219)
102 (26426 -17361 -6618)
103 (-15311 -6387 -5902)
104 (22737 14339 16074)
105 (-28136 21003 -11594)
106 (-11020 -32377 -4866)
107 (-24024 10995 22766)
108 (3438 -19758 -10931)
109 (28839 22032 -7204)
110 (-25237 23224 26189)
============== VERIFY WITH sed:
101 15400 5215 -20219,
102 26426 -17361 -6618,
103 -15311 -6387 -5902,
104 22737 14339 16074,
105 -28136 21003 -11594,
106 -11020 -32377 -4866,
107 -24024 10995 22766,
108 3438 -19758 -10931,
109 28839 22032 -7204,
110 -25237 23224 26189,
答案 1 :(得分:2)
仅仅因为我想了解更多关于Spirit X3的信息,并且因为世界想要了解更多关于这个即将推出的库的版本,这里有一个更复杂的版本,它显示了根据某种表达式动态过滤行的方法。 / p>
在这种情况下,这些行由此处理程序处理:
auto handle = [&](auto& ctx) mutable {
using boost::fusion::at_c;
if (++line_no % 10 == 0)
{
auto& attr = x3::_attr(ctx);
data.push_back({ at_c<0>(attr), at_c<1>(attr), at_c<2>(attr) });
}
};
正如您所期望的那样,每10行都包括在内。
<强> Live On Coliru 强>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <iostream>
namespace x3 = boost::spirit::x3;
int main() {
using It = boost::spirit::istream_iterator;
It f(std::cin >> std::noskipws), l;
struct Tup { int a, b, c; };
std::vector<Tup> data;
size_t line_no = 0;
auto handle = [&](auto& ctx) mutable {
using boost::fusion::at_c;
if (++line_no % 10 == 0)
{
auto& attr = x3::_attr(ctx);
data.push_back({ at_c<0>(attr), at_c<1>(attr), at_c<2>(attr) });
}
};
if (x3::phrase_parse(f, l, (x3::int_ >> x3::int_ >> x3::int_) [ handle ] % (',' >> x3::eol), x3::blank))
{
for(auto tup : data)
std::cout << tup.a << " " << tup.b << " " << tup.c << "\n";
}
}
打印例如。
g++ -std=c++1y -O2 -Wall -pedantic -pthread main.cpp -o test
od -Anone -t d2 /dev/urandom -w6 | sed 's/$/,/g' | head -200 | tee log | ./test
echo ============== VERIFY WITH perl:
nl log | perl -ne 'print if $. % 10 == 0'
-8834 -947 -8151
13789 -20056 -11874
6919 -27211 -19472
-7644 18021 13523
-20120 16923 -11419
27772 31149 14005
3540 4894 -24790
10698 10223 -30397
-22533 -32437 -13665
25813 3264 -16414
11453 11955 18268
5092 27052 17930
10915 6493 20432
-14380 -6085 -25430
18599 6710 17279
22049 22259 -32189
1048 14621 6452
-24996 10856 29429
3537 -26338 19623
-4117 6617 14009
============== VERIFY WITH perl:
10 -8834 -947 -8151,
20 13789 -20056 -11874,
30 6919 -27211 -19472,
40 -7644 18021 13523,
50 -20120 16923 -11419,
60 27772 31149 14005,
70 3540 4894 -24790,
80 10698 10223 -30397,
90 -22533 -32437 -13665,
100 25813 3264 -16414,
110 11453 11955 18268,
120 5092 27052 17930,
130 10915 6493 20432,
140 -14380 -6085 -25430,
150 18599 6710 17279,
160 22049 22259 -32189,
170 1048 14621 6452,
180 -24996 10856 29429,
190 3537 -26338 19623,
200 -4117 6617 14009,