如何通过分隔符标记字符串?
Posted
技术标签:
【中文标题】如何通过分隔符标记字符串?【英文标题】:How to tokenize string by delimiters? 【发布时间】:2015-02-05 22:19:54 【问题描述】:我需要用分隔符标记字符串。
例如:
对于"One, Two Three,,, Four"
,我需要得到"One", "Two", "Three", "Four"
。
我正在尝试使用这个解决方案https://***.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'
【问题讨论】:
该错误是否与您向我们展示的代码行之一有关? 您链接到的解决方案不使用c_str()
。我假设 boost 要求参数是以 STL 为中心的,即有一个 begin()
迭代器。
@DrewDormann 该错误是指 tokenizer.hpp: template 改变这个:
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::char_separatorchar *
。对于您描述的任务,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
表示您的,,,
输入不应在这些逗号之间暗示空字符串标记。
【讨论】:
我见过这个解决方案。当达到某个大小时,我可以停止添加令牌吗? @Ufx 一次性完成,所以如果你想要返回向量的最大尺寸,你可以在返回之前调整它的大小。【参考方案3】:捷径。
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;
【讨论】:
【参考方案4】:我看到很多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
可以是任何修剪功能,我使用了this SO answer。它利用std::back_inserter
和递归。您可以轻松地循环执行此操作,但这听起来更有趣:)
【讨论】:
以上是关于如何通过分隔符标记字符串?的主要内容,如果未能解决你的问题,请参考以下文章