将string拆分为多个分隔符
我有一些文本(有意义的文本或算术expression),我想把它分解成单词。
如果我有一个单独的分隔符,我会使用:
std::stringstream stringStream(inputString); std::string word; while(std::getline(stringStream, word, delimiter)) { wordVector.push_back(word); }
我怎样才能把string分成几个分隔符的标记?
假设其中一个分隔符是换行符,下面的内容会读取该行并进一步将其分隔符分隔。 对于这个例子,我select了分隔符空格,撇号和分号。
std::stringstream stringStream(inputString); std::string line; while(std::getline(stringStream, line)) { std::size_t prev = 0, pos; while ((pos = line.find_first_of(" ';", prev)) != std::string::npos) { if (pos > prev) wordVector.push_back(line.substr(prev, pos-prev)); prev = pos+1; } if (prev < line.length()) wordVector.push_back(line.substr(prev, std::string::npos)); }
如果你有提升,你可以使用:
#include <boost/algorithm/string.hpp> std::string inputString("One!Two,Three:Four"); std::string delimiters("|,:"); std::vector<std::string> parts; boost::split(parts, inputString, boost::is_any_of(delimiters));
我不知道为什么没有人指出手动的方式,但这里是:
const std::string delims(";,:. \n\t"); inline bool isDelim(char c) { for (int i = 0; i < delims.size(); ++i) if (delims[i] == c) return true; return false; }
在function上:
std::stringstream stringStream(inputString); std::string word; char c; while (stringStream) { word.clear(); // Read word while (!isDelim((c = stringStream.get()))) word.push_back(c); if (c != EOF) stringStream.unget(); wordVector.push_back(word); // Read delims while (isDelim((c = stringStream.get()))); if (c != EOF) stringStream.unget(); }
这样,你可以做一些有用的分界符,如果你想。
如果你有兴趣如何自己做,而不是使用提升。
假设分隔符string可能非常长 – 比如说M,检查string中的每个字符(如果是分隔符的话)都会花费O(M),所以在原始string中的所有字符都循环,在长度N,是O(M * N)。
我会使用一个字典(如地图 – “分隔符”“布尔” – 但在这里我会使用一个简单的布尔数组,在每个分隔符index = ascii值为真)。
现在迭代string,并检查是否是分隔符是O(1),最终给我们O(N)整体。
这是我的示例代码:
const int dictSize = 256; vector<string> tokenizeMyString(const string &s, const string &del) { static bool dict[dictSize] = { false}; vector<string> res; for (int i = 0; i < del.size(); ++i) { dict[del[i]] = true; } string token(""); for (auto &i : s) { if (dict[i]) { if (!token.empty()) { res.push_back(token); token.clear(); } } else { token += i; } } if (!token.empty()) { res.push_back(token); } return res; } int main() { string delString = "MyDog:Odie, MyCat:Garfield MyNumber:1001001"; //the delimiters are " " (space) and "," (comma) vector<string> res = tokenizeMyString(delString, " ,"); for (auto &i : res) { cout << "token: " << i << endl; } return 0; }
注意:tokenizeMyString按值返回vector,并首先在堆栈上创build它,所以我们在这里使用了编译器的威力>>> RVO – 返回值优化:)