boost::split在字符串的开头和结尾留下空标记 - 这是所需的行为

boost::split leaves empty tokens at the beginning and end of string - is this desired behaviour?

本文关键字:字符串 split 开头 boost 结尾      更新时间:2023-10-16

由于我在文档中找不到任何关于此的内容,我想我在这里问它。我有以下程序 (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)

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

如果确实需要删除前导/尾随空格,则应按原样trim_iftrim

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

这里

它不会删除令牌,只会合并它们。

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

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

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

这种行为类似于python

>>> len("".split(','))
1