拆分具有多个分隔符的字符串,允许引用值

时间:2017-04-27 21:03:17

标签: c++ string boost boost-tokenizer

boost::escaped_list_separator的{​​{3}}为第二个参数c提供了以下说明:

  

字符串c中的任何字符都被视为分隔符。

所以,我需要用多个分隔符拆分字符串,允许引用的值,它们可以包含这些分隔符:

#include <iostream>
#include <string>

#include <boost/tokenizer.hpp>

int main() {
    std::wstring str = L"2   , 14   33  50   \"AAA BBB\"";

    std::wstring escSep(L"\\"); //escape character
    std::wstring delim(L" \t\r\n,"); //split on spaces, tabs, new lines, commas
    std::wstring quotes(L"\""); //allow double-quoted values with delimiters within

    boost::escaped_list_separator<wchar_t> separator(escSep, delim, quotes);
    boost::tokenizer<boost::escaped_list_separator<wchar_t>, std::wstring::const_iterator, std::wstring> tok(str, separator);

    for(auto beg=tok.begin(); beg!=tok.end();++beg)
        std::wcout << *beg << std::endl;

    return 0;
}

预期结果将是[2; 14; 33; 50; AAA BBB]。但是,他的代码docs是一堆空标记:

results

常规boost::char_separator省略所有这些空标记,考虑所有分隔符。似乎boost::escaped_list_separator也会考虑所有指定的分隔符,但会生成空值。如果遇到多个连续的分隔符,它会产生空标记吗?有什么方法可以避免这种情况吗?

如果它始终为真,那么只生成空标记,可以很容易地测试结果值并手动省略它们。但是,它可能变得非常难看。例如,想象每个字符串都有2个实际值,并且可能有许多选项卡和空格分隔值。然后将分隔符指定为L"\t "(即空格和制表符)将起作用,但会生成大量空标记。

1 个答案:

答案 0 :(得分:2)

根据Boost Tokenizer文档判断,如果遇到多个连续的分隔符,您确实是正确的,在使用boost::escaped_list_separator时会产生空标记。与boost::char_separator不同,boost::escaped_list_separator不提供任何允许您传入是否保留或丢弃任何空标记的构造函数。

虽然可以选择丢弃空标记,但是当您考虑文档(http://www.boost.org/doc/libs/1_64_0/libs/tokenizer/escaped_list_separator.htm)中提供的用例(解析CSV文件)时,保留空标记非常有意义。空字段仍然是字段。

一种选择是在标记化后简单地丢弃空标记。如果生成空标记会引起您的注意,另一种方法是在将重复分隔符传递给标记器之前删除重复的分隔符,但显然您需要注意不要删除引号内的任何内容。