在C ++中使用string分隔符(标准C ++)parsing(拆分)一个string

可能重复:
在C ++中分割一个string

我在C ++中使用以下parsingstring:

string parsed,input="text to be parsed"; stringstream input_stringstream(input); if(getline(input_stringstream,parsed,' ')) { // do some processing. } 

使用单个字符分隔符进行parsing很好。 但是,如果我想使用一个string作为分隔符。

例如:我想分割:

 scott>=tiger 

> =作为分隔符,以便我可以得到斯科特和老虎。

您可以使用std::string::find()函数来查找string分隔符的位置,然后使用std::string::substr()来获取一个标记。

例:

 std::string s = "scott>=tiger"; std::string delimiter = ">="; std::string token = s.substr(0, s.find(delimiter)); // token is "scott" 
  • find(const string& str, size_t pos = 0)函数返回string中str的第一个出现位置,如果找不到string,则npos

  • substr(size_t pos = 0, size_t n = npos)函数返回对象的一个​​子string,从位置pos开始,长度为npos


如果你有多个分隔符,当你提取一个标记后,你可以删除它(包括分隔符)以进行后续的提取(如果你想保留原始的string,只需使用s = s.substr(pos + delimiter.length()); ):

 s.erase(0, s.find(delimiter) + delimiter.length()); 

这样你可以很容易地循环获取每个令牌。

完整的例子

 std::string s = "scott>=tiger>=mushroom"; std::string delimiter = ">="; size_t pos = 0; std::string token; while ((pos = s.find(delimiter)) != std::string::npos) { token = s.substr(0, pos); std::cout << token << std::endl; s.erase(0, pos + delimiter.length()); } std::cout << s << std::endl; 

输出:

 scott tiger mushroom 

此方法使用std::string::find而不用通过记住前一个子串标记的开始和结束来改变原始string。

 #include <iostream> #include <string> int main() { std::string s = "scott>=tiger"; std::string delim = ">="; auto start = 0U; auto end = s.find(delim); while (end != std::string::npos) { std::cout << s.substr(start, end - start) << std::endl; start = end + delim.length(); end = s.find(delim, start); } std::cout << s.substr(start, end); } 

strtok允许你传入多个字符作为分隔符。 我敢打赌,如果你传入“> =”你的示例string将被正确拆分(即使>和=被视为单独的分隔符)。

编辑如果你不想使用c_str()从string转换为char *,你可以使用substr和find_first_of标记。

 string token, mystring("scott>=tiger"); while(token != mystring){ token = mystring.substr(0,mystring.find_first_of(">=")); mystring = mystring.substr(mystring.find_first_of(">=") + 1); printf("%s ",token.c_str()); } 

你可以使用下一个函数来拆分string:

 vector<string> split(const string& str, const string& delim) { vector<string> tokens; size_t prev = 0, pos = 0; do { pos = str.find(delim, prev); if (pos == string::npos) pos = str.length(); string token = str.substr(prev, pos-prev); if (!token.empty()) tokens.push_back(token); prev = pos + delim.length(); } while (pos < str.length() && prev < str.length()); return tokens; } 

这段代码将文本中的行分开,并将所有人添加到一个向量中。

 vector<string> split(char *phrase, string delimiter){ vector<string> list; string s = string(phrase); size_t pos = 0; string token; while ((pos = s.find(delimiter)) != string::npos) { token = s.substr(0, pos); list.push_back(token); s.erase(0, pos + delimiter.length()); } return list; } 

调用人:

 vector<string> listFilesMax = split(buffer, "\n"); 

我会使用boost::tokenizer 。 以下是解释如何制作合适的标记器函数的文档: http : //www.boost.org/doc/libs/1_52_0/libs/tokenizer/tokenizerfunction.htm

这是一个适合你的情况。

 struct my_tokenizer_func { template<typename It> bool operator()(It& next, It end, std::string & tok) { if (next == end) return false; char const * del = ">="; auto pos = std::search(next, end, del, del + 2); tok.assign(next, pos); next = pos; if (next != end) std::advance(next, 2); return true; } void reset() {} }; int main() { std::string to_be_parsed = "1) one>=2) two>=3) three>=4) four"; for (auto i : boost::tokenizer<my_tokenizer_func>(to_be_parsed)) std::cout << i << '\n'; } 

这是我的承担。 它处理边缘情况并采用可选参数从结果中删除空条目。

 bool endsWith(const std::string& s, const std::string& suffix) { return s.size() >= suffix.size() && s.substr(s.size() - suffix.size()) == suffix; } std::vector<std::string> split(const std::string& s, const std::string& delimiter, const bool& removeEmptyEntries = false) { std::vector<std::string> tokens; for (size_t start = 0, end; start < s.length(); start = end + delimiter.length()) { size_t position = s.find(delimiter, start); end = position != string::npos ? position : s.length(); std::string token = s.substr(start, end - start); if (!removeEmptyEntries || !token.empty()) { tokens.push_back(token); } } if (!removeEmptyEntries && (s.empty() || endsWith(s, delimiter))) { tokens.push_back(""); } return tokens; } 

例子

 split("abc", "-"); // [3]("a","b","c") split("a--c", "-"); // [3]("a","","c") split("-b-", "-"); // [3]("","b","") split("--c--", "-"); // [5]("","","c","","") split("--c--", "-", true); // [1]("c") split("a", "-"); // [1]("a") split("", "-"); // [1]("") split("", "-", true); // [0]() 

如果你不想修改string(如Vincenzo Pii的答案) 并且想要输出最后一个标记,那么你可能想要使用这种方法:

 inline std::vector<std::string> splitString( const std::string &s, const std::string &delimiter ){ std::vector<std::string> ret; size_t start = 0; size_t end = 0; size_t len = 0; std::string token; do{ end = s.find(delimiter,start); len = end - start; token = s.substr(start, len); ret.emplace_back( token ); start += len + delimiter.length(); std::cout << token << std::endl; }while ( end != std::string::npos ); return ret; } 

用于string分隔符
根据分隔string拆分string。 如基于分隔符string"-+"分割string"adsf-+qwret-+nvfkbdsj-+orthdfjgh-+dfjrleih" ,输出将为{"adsf", "qwret", "nvfkbdsj", "orthdfjgh", "dfjrleih"}

 #include <iostream> #include <sstream> #include <vector> using namespace std; // for string delimiter vector<string> split(string s, string delimiter) { size_t pos_start = 0, pos_end, delim_len = delimiter.length(); string token; vector<string> res; while ((pos_end = s.find(delimiter, pos_start)) != string::npos) { token = s.substr(pos_start, pos_end - pos_start); pos_start = pos_end + delim_len; res.push_back(token); } res.push_back(s.substr(pos_start)); return res; } int main() { string str = "adsf-+qwret-+nvfkbdsj-+orthdfjgh-+dfjrleih"; string delimiter = "-+"; vector<string> v = split(str, delimiter); for (auto i : v) cout << i << endl; return 0; } 

对于单个字符分隔符

 #include <iostream> #include <sstream> #include <vector> using namespace std; vector<string> split(const string &s, char delim) { vector<string> result; stringstream ss(s); string item; while (getline(ss, item, delim)) { result.push_back(item); } return result; } int main() { string str = "adsf+qwer+poui+fdgh"; vector<string> v = split(str, '+'); for (auto i : v) cout << i << endl; return 0; } 
 std::vector<std::string> split(const std::string& s, char c) { std::vector<std::string> v; unsigned int ii = 0; unsigned int j = s.find(c); while (j < s.length()) { v.push_back(s.substr(i, j - i)); i = ++j; j = s.find(c, j); if (j >= s.length()) { v.push_back(s.substr(i, s,length())); break; } } return v; }