如何通过分隔符标记字符串

How to tokenize string by delimiters?

本文关键字:字符串 分隔符 何通过      更新时间:2023-10-16

我需要用分隔符标记字符串。

例如:

对于"One, Two Three,,, Four",我需要得到{"One", "Two", "Three", "Four"}

我正试图利用这种方法https://stackoverflow.com/a/55680/1034253

std::vector<std::string> strToArray(const std::string &str,
                                    const std::string &delimiters = " ,")
{
    boost::char_separator<char> sep(delimiters.c_str());
    boost::tokenizer<boost::char_separator<char>> tokens(str.c_str(), sep);
    std::vector<std::string> result;
    for (const auto &token: tokens) {
        result.push_back(token);
    }
    return result;
}

但我得到了错误:

boost-1_57\boost/tokenizer.hpp(62):错误C2228:'.begin'的左侧必须具有类/结构/并集类型为"const char*const"

更改此项:

boost::tokenizer<boost::char_separator<char>> tokens(str.c_str(), sep);

对此:

boost::tokenizer<boost::char_separator<char>> tokens(str, sep);

链接:http://www.boost.org/doc/libs/1_57_0/libs/tokenizer/tokenizer.htm

容器类型需要一个begin()函数,而返回的const char*(这就是c_str())不满足此要求。

Boost的标记化器对于您描述的任务来说可能有些过头了。

boost::split就是为这个任务编写的。

std::vector<std::string> strToArray(const std::string &str,
                                    const std::string &delimiters = " ,")
{
    using namespace boost;
    std::vector<std::string> result;
    split( result, str, is_any_of(delimiters), token_compress_on );
    return result;
}

该可选的token_compress_on表示您的,,,输入不应在这些逗号之间暗示空字符串标记

捷径。

string tmp = "One, Two, Tree, Four";
int pos = 0;
while (pos = tmp.find(", ") and pos > 0){
    string s = tmp.substr(0, pos);
    tmp = tmp.substr(pos+2);
    cout << s;
}

我看到了很多boost的答案,所以我想我应该提供一个非boost的答案:

template <typename OutputIter>
void Str2Arr( const std::string &str, const std::string &delim, int start, bool ignoreEmpty, OutputIter iter )
{
    int pos = str.find_first_of( delim, start );
    if (pos != std::string::npos) {
        std::string nStr = str.substr( start, pos - start );
        trim( nStr );
        if (!nStr.empty() || !ignoreEmpty)
            *iter++ = nStr;
        Str2Arr( str, delim, pos + 1, ignoreEmpty, iter );
    }
    else
    {
        std::string nStr = str.substr( start, str.length() - start );
        trim( nStr );
        if (!nStr.empty() || !ignoreEmpty)
          *iter++ = nStr;
    }
}
std::vector<std::string> Str2Arr( const std::string &str, const std::string &delim )
{
    std::vector<std::string> result;
    Str2Arr( str, delim, 0, true, std::back_inserter( result ) );
    return std::move( result );
}

trim可以是任何修剪函数,我使用了这个SO答案。它利用了CCD_ 11和递归。你可以很容易地在一个循环中完成,但这听起来更有趣:)