Разделить строку по первым N вхождениям разделителя, используя boost :: split - PullRequest
0 голосов
/ 07 июня 2018

Я знаю, что, возможно, это глупый вопрос, но я пока не нашел ответа.Предположим, у меня есть следующая строка:

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 голосов
/ 07 июня 2018

Вы можете использовать:

find_nth(str, ",", 1);

из <boost/algorithm/string/find.hpp>, чтобы найти 2-е (или n-е) вхождение интересующего вас персонажа.

Затем используйте традиционный substr() для этогоpossition.

Затем токенизируйте первую часть строки boost :: split.И добавьте последнюю часть к вектору.

0 голосов
/ 07 июня 2018

Вы можете использовать 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";
}

Демонстрационная версия

Хитрость здесь заключается в том, чтобы рассматривать запятые как пробельные символы, которыеможет быть сделано в ctype<> фасете.

...