11

由于我在文档中找不到任何关于此的内容,我想我在这里问它。我有以下程序(C++ 11):

#include <iostream> 
#include <boost/algorithm/string.hpp>

using namespace std;
using namespace boost;

int main () {
    string tmp = " #tag #tag1#tag2  #tag3 ####tag4   ";
    list<iterator_range<string::iterator> > matches;
    split( matches, tmp, is_any_of("\t #"), token_compress_on );

    for( auto match: matches ) {
            cout << "'" << match << "'\n";
    }
}

输出是:

''
'tag'
'tag1'
'tag2'
'tag3'
'tag4'
''

我原以为该token_compress_on选项会删除所有空标记。例如,解决方案是使用boost::trim_if. 不过我想知道这是否是 boost::split 的期望行为,为什么会这样?

(g++ 4.6.3,提升 1.48)

4

3 回答 3

8

如果eCompress参数设置为token_compress_on,则将相邻的分隔符合并在一起。否则,每两个分隔符分隔一个标记。

这里

它不会删除标记,只会合并它们。

于 2012-05-03T18:56:00.040 回答
8

该行为是有意的,因为您可以从拆分版本重新创建字符串(完整的起始和尾随空格)。Boost 不知道该空格对您是否重要(例如,某些文件格式可能会强制使用前导空格/特定空间计数)。

如果确实需要删除前导/尾随空格,则应该trim_if或按原样进行。trim

于 2012-05-03T18:46:00.803 回答
2

boost::split总是返回n + 1标记,其中n是输入字符串中的分隔符数。因此,当您将一个空字符串传递给它时,当它返回 1 个令牌时不要感到惊讶。

其背后的理由很简单。假设您正在解析一个 CSV 文件。无论最后一个标记是否为空,您都需要获得完全相同数量的元素。

删除空标记比猜测它们是否应该出现在结果中要容易得多。信用

这种行为类似于python

>>> len("".split(','))
1
于 2017-01-12T01:52:10.920 回答