我正在使用boost字符串库,并且刚刚遇到了分割方法的简单易用性。
string delimiters = ",";
string str = "string, with, comma, delimited, tokens, \"and delimiters, inside a quote\"";
// If we didn't care about delimiter characters within a quoted section we could us
vector<string> tokens;
boost::split(tokens, str, boost::is_any_of(delimiters));
// gives the wrong result: tokens = {"string", " with", " comma", " delimited", " tokens", "\"and delimiters", " inside a quote\""}
哪个好看又简洁......但它似乎不适用于引号而是我必须做类似以下的事情
string delimiters = ",";
string str = "string, with, comma, delimited, tokens, \"and delimiters, inside a quote\"";
vector<string> tokens;
escaped_list_separator<char> separator("\\",delimiters, "\"");
typedef tokenizer<escaped_list_separator<char> > Tokeniser;
Tokeniser t(str, separator);
for (Tokeniser::iterator it = t.begin(); it != t.end(); ++it)
tokens.push_back(*it);
// gives the correct result: tokens = {"string", " with", " comma", " delimited", " tokens", "\"and delimiters, inside a quote\""}
当你引用分隔符时,我的问题是可以拆分还是使用其他标准算法?感谢purpledog,但我已经有了一种不贬低的方法来实现预期的结果,我只是认为它非常麻烦,除非我能用更简单,更优雅的解决方案替换它,我不会在没有首先将其包装的情况下使用它另一种方法。
编辑:更新了代码以显示结果并澄清问题。
答案 0 :(得分:5)
使用boost :: split方法似乎没有任何简单的方法可以做到这一点。我能找到的最短的代码是
vector<string> tokens;
tokenizer<escaped_list_separator<char> > t(str, escaped_list_separator<char>("\\", ",", "\""));
BOOST_FOREACH(string s, escTokeniser)
tokens.push_back(s);
只比原始片段
略微冗长vector<string> tokens;
boost::split(tokens, str, boost::is_any_of(","));
答案 1 :(得分:2)
这将获得与Jamie Cook在没有显式循环的情况下的答案相同的结果。
tokenizer<escaped_list_separator<char> >tok(str);
vector<string> tokens( tok.begin(), tok.end() );
tokenizer构造函数的第二个参数默认为escaped_list_separator<char>("\\", ",", "\"")
,因此没有必要。除非您对逗号或引号有不同的要求。
答案 2 :(得分:1)
我不知道boost :: string库,但是使用boost regex_token_iterator你可以用正则表达式来表达分隔符。所以,是的,您可以使用带引号的分隔符,也可以使用更复杂的分隔符。
请注意,这曾经使用regex_split来完成,现在已弃用。
以下是来自boost doc的示例:
#include <iostream>
#include <boost/regex.hpp>
using namespace std;
int main(int argc)
{
string s;
do{
if(argc == 1)
{
cout << "Enter text to split (or \"quit\" to exit): ";
getline(cin, s);
if(s == "quit") break;
}
else
s = "This is a string of tokens";
boost::regex re("\\s+");
boost::sregex_token_iterator i(s.begin(), s.end(), re, -1);
boost::sregex_token_iterator j;
unsigned count = 0;
while(i != j)
{
cout << *i++ << endl;
count++;
}
cout << "There were " << count << " tokens found." << endl;
}while(argc == 1);
return 0;
}
如果程序以 hello world 作为参数启动,则输出为:
hello
world
There were 2 tokens found.
将 boost :: regex re(“\ s +”); 更改为 boost :: regex re(“\”,\“”); 会拆分引用的分隔符。以 hello“,”world 作为参数启动程序也会导致:
hello
world
There were 2 tokens found.
但我怀疑你想要处理类似的事情:“你好”,“世界”,在这种情况下,一个解决方案是:
编辑:添加了程序输出