如何将一个string的所有实例replace为另一个string?

我在另一个堆栈问题上find了

//http://stackoverflow.com/questions/3418231/c-replace-part-of-a-string-with-another-string // void replaceAll(std::string& str, const std::string& from, const std::string& to) { size_t start_pos = 0; while((start_pos = str.find(from, start_pos)) != std::string::npos) { size_t end_pos = start_pos + from.length(); str.replace(start_pos, end_pos, to); start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx' } } 

和我的方法:

 string convert_FANN_array_to_binary(string fann_array) { string result = fann_array; cout << result << "\n"; replaceAll(result, "-1 ", "0"); cout << result << "\n"; replaceAll(result, "1 ", "1"); return result; } 

其中,对于这个input:

 cout << convert_FANN_array_to_binary("1 1 -1 -1 1 1 "); 

现在,输出应该是“110011”

这里是方法的输出:

 1 1 -1 -1 1 1 // original 1 1 0 1 // replacing -1's with 0's 11 1 // result, as it was returned from convert_FANN_array_to_binary() 

我一直在查看replaceAll代码,我真的不知道为什么它将一个0replace连续的-1,然后在最终结果中不返回任何0(和一些1)。 = \

错误在str.replace(start_pos, end_pos, to);

http://www.cplusplus.com/reference/string/string/replace/上的std :: string文档

 string& replace ( size_t pos1, size_t n1, const string& str ); 

您正在使用结束位置,而函数需要一个长度。

所以改成:

 while((start_pos = str.find(from, start_pos)) != std::string::npos) { str.replace(start_pos, from.length(), to); start_pos += to.length(); // ... } 

注意:未经testing。

一个完整的代码:

 std::string ReplaceString(std::string subject, const std::string& search, const std::string& replace) { size_t pos = 0; while ((pos = subject.find(search, pos)) != std::string::npos) { subject.replace(pos, search.length(), replace); pos += replace.length(); } return subject; } 

如果你需要性能,这是一个更优化的函数,它修改了inputstring,它不创buildstring的副本:

 void ReplaceStringInPlace(std::string& subject, const std::string& search, const std::string& replace) { size_t pos = 0; while ((pos = subject.find(search, pos)) != std::string::npos) { subject.replace(pos, search.length(), replace); pos += replace.length(); } } 

testing:

 std::string input = "abc abc def"; std::cout << "Input string: " << input << std::endl; std::cout << "ReplaceString() return value: " << ReplaceString(input, "bc", "!!") << std::endl; std::cout << "ReplaceString() input string not changed: " << input << std::endl; ReplaceStringInPlace(input, "bc", "??"); std::cout << "ReplaceStringInPlace() input string modified: " << input << std::endl; 

输出:

 Input string: abc abc def ReplaceString() return value: a!! a!! def ReplaceString() input string not changed: abc abc def ReplaceStringInPlace() input string modified: a?? a?? def 

这将在我的“只使用一个Boost库”的答案列表中,但是在这里它无论如何:

你有没有考虑过Boost.String ? 它具有比标准库更多的function,并且在function重叠的地方,我认为Boost.String具有更自然的语法。

我发现在以前的答案中给出的replace函数,全部在内部使用str.replace()调用,处理大约2 MB长度的string时非常慢。 具体来说,我调用了像ReplaceAll(str,“\ r”,“”),并在我的特定设备上,包含很多换行符的文本文件,大约需要27秒。 然后我用函数replace它,只是在一个新的副本中连接子string,只花了大约1秒。 这是我的版本的ReplaceAll():

 void replaceAll(string& str, const string& from, const string& to) { if(from.empty()) return; string wsRet; wsRet.reserve(str.length()); size_t start_pos = 0, pos; while((pos = str.find(from, start_pos)) != string::npos) { wsRet += str.substr(start_pos, pos - start_pos); wsRet += to; pos += from.length(); start_pos = pos; } wsRet += str.substr(start_pos); str.swap(wsRet); // faster than str = wsRet; } 

格雷格

C ++ 11现在包含具有正则expression式function的头<regex> 。 从文档 :

 // regex_replace example #include <iostream> #include <string> #include <regex> #include <iterator> int main () { std::string s ("there is a subsequence in the string\n"); std::regex e ("\\b(sub)([^ ]*)"); // matches words beginning by "sub" // using string/c-string (3) version: std::cout << std::regex_replace (s,e,"sub-$2"); std::cout << std::endl; return 0; } 

当然, 现在你有两个问题 。

尝试这个:

 #include <string> string replace_str(string & str, const string & from, const string & to) { while(str.find(from) != string::npos) str.replace(str.find(from), from.length(), to); return str; }