读取行分隔的字符串列表时跳过空白行

时间:2014-11-13 06:36:34

标签: c++ boost-spirit-qi

我尝试使用boost :: spirit解析一个简单的文本文件。文本文件是以行分隔的字符串列表。除了涉及到空白行之外,我可以把它主要用于工作,我想跳过它。

我尝试了几种方法,但我要么停止在空行处解析,要么在结果中包含空白行。

有没有办法告诉我的语法跳过空行?

std::ifstream ifs("one.txt");
ifs >> std::noskipws;

std::vector< std::string > people;

if (parse(
     istream_iterator(ifs),
     istream_iterator(),
     *(as_string[+print >> (eol | eoi)]),
     people))
{
  std::cout << "Size = " << people.size() << std::endl;

  for (auto person : people)
  {
     std::cout << person << std::endl;
  }
}

此时就把one.txt存盘

Sally
Joe
Frank
Mary Ann

Bob

我得到了什么

Sally
Joe
Frank
Mary Ann

我想得到什么

Sally
Joe
Frank
Mary Ann
Bob

奖金:我可以同时从语法中的行中删除前导或尾随空格吗?我当然需要保留玛丽安的空间。

1 个答案:

答案 0 :(得分:1)

if (qi::phrase_parse(
            first, last,
            -qi::as_string[qi::lexeme[+(qi::char_ - qi::eol)]] % qi::eol,
            qi::blank,
            people))

我会参考 Boost spirit skipper issues 了解更多背景信息。快速说明:

if (qi::phrase_parse(
//      ^ ----- use a skipper to parse phrases whith a skipper (`qi::blank` here)
            first, last,
            -qi::as_string[qi::lexeme[+(qi::char_ - qi::eol)]] % qi::eol,
//          |                  |      |                          ^---- 1.
//          +---- 2.           |      +---- 4.
//       5. ----v       3. ----+      
            qi::blank,
            people))
  1. 匹配由换行符分隔的项目列表
  2. &#39; - &#39;使项目可选(忽略空行)
  3. lexeme包含子表达式中的空格(但它仍然预先跳过,因此只有空格的行计为空行;如果您不想要预先录制,请使用no_skip
  4. +至少需要1个匹配项,因此空名称不会被视为名称
  5. blank队长跳过空白,但不跳过换行符;这是因为换行符对你的语法很重要。另请注意,lexeme仍保留内部空白
  6. 查看 Live On Coliru

    更新为了回应评论,增加的复杂性是由于跳过空白。如果您愿意在事后修剪空白,请务必使用

    if (parse(first, last, - as_string[+(char_ - eol)] % eol, people))
    

    同时查看 Live On Coliru