使用boost :: split在前N次出现的分隔符中拆分字符串

时间:2018-06-07 16:34:40

标签: c++ boost split

我知道这可能是一个愚蠢的问题,但我还没有找到答案。我们假设我有以下字符串:

std::string str("1,2,3,4,5,6,7,8,9,10");

我想使用逗号作为分隔符将其拆分,但仅限于前N次出现。例如,对于N = 2,我应该得到结果:

{ "1", "2", "3,4,5,6,7,8,9,10" }.

是否可以使用boost::split执行此操作?我总是以下面的形式使用它:

std::vector<std::string> values;
boost::split(values, str, boost::is_any_of(","), boost::token_compress_on);

将字符串拆分在分隔符的每个出现位置。

如果不可能,有人可以建议我这样做的有效方法吗? 我想避免处理正则表达式,我。即我想写一个像:

这样的函数
std::vector<std::string> tokenize(const std::string& to_split, const std::string& delimiter, int occurrences)

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

您可以使用:

find_nth(str, ",", 1);

<boost/algorithm/string/find.hpp>找到感兴趣字符的第二(或第n)次出现。

然后使用传统的substr()

然后将字符串boost :: split的第一部分标记化。 并将最后一部分添加到矢量中。

答案 1 :(得分:0)

您可以使用stringstream和修改后的区域设置:

#include <iostream>
#include <string>
#include <vector>
#include <sstream>

struct csv_whitespace : std::ctype<char> {
    static const mask* make_table() {
        static std::vector<mask> v(classic_table(), 
                                   classic_table() + table_size);
        v[','] |= space;
        v[' '] &= ~space;
        return &v[0];
    }

    csv_whitespace(std::size_t refs = 0) 
       : std::ctype<char>{ make_table(), false, refs } { }
};

int main() {
    std::string str("1,2,3,4,5,6,7,8,9,10");
    std::stringstream ss(str);
    auto loc = ss.getloc();
    ss.imbue(std::locale(loc, new csv_whitespace));
    std::size_t N = 3;
    while(N--) {
        std::string a;
        ss >> a;
        std::cout << a << '\n';
    }
    ss.ignore();
    ss.imbue(loc);
    std::string rest;
    ss >> rest;
    std::cout << "Rest: " << rest << "\n";
}

Live demo

这里的诀窍是将逗号视为空格,可以在ctype<>方面完成。