C++ 如何用另一个字符串替换一个字符串的所有实例?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5343190/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I replace all instances of a string with another string?
提问by NullVoxPopuli
I found this on another stack question:
我在另一个堆栈问题上发现了这个:
//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'
}
}
and my method:
和我的方法:
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;
}
which, for this input:
其中,对于此输入:
cout << convert_FANN_array_to_binary("1 1 -1 -1 1 1 ");
now, the output should be "110011"
现在,输出应该是“110011”
here is the output of the method:
这是该方法的输出:
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()
I've been looking at the replaceAll code, and, I'm really not sure why it is replacing consecutive -1's with one 0, and then not returning any 0's (and some 1's) in the final result. =\
我一直在查看 replaceAll 代码,我真的不知道为什么它用一个 0 替换连续的 -1,然后在最终结果中不返回任何 0(和一些 1)。=\
采纳答案by Sjoerd
The bug is in str.replace(start_pos, end_pos, to);
错误在 str.replace(start_pos, end_pos, to);
From the std::string doc at http://www.cplusplus.com/reference/string/string/replace/
来自http://www.cplusplus.com/reference/string/string/replace/的 std::string 文档
string& replace ( size_t pos1, size_t n1, const string& str );
You are using an end-position, while the function expects a length.
您正在使用结束位置,而函数需要一个长度。
So change to:
所以改为:
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length(); // ...
}
Note: untested.
注:未经测试。
回答by Czarek Tomczak
A complete code:
一个完整的代码:
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;
}
If you need performance, here is a more optimized function that modifies the input string, it does not create a copy of the string:
如果您需要性能,这里有一个更优化的函数来修改输入字符串,它不会创建字符串的副本:
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();
}
}
Tests:
测试:
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;
Output:
输出:
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
回答by phooji
This is going to go in my list of 'just use a Boost library' answers, but here it goes anyway:
这将出现在我的“只使用 Boost 库”答案列表中,但无论如何都在这里:
Have you considered Boost.String? It has more features than the standard library, and where features overlap, Boost.String has a more much more natural syntax, in my opinion.
你考虑过Boost.String吗?在我看来,它比标准库具有更多的特性,并且在特性重叠的地方,Boost.String 具有更自然的语法。
回答by Jherico
C++11 now includes the header <regex>
which has regular expression functionality. From the docs:
C++11 现在包含<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-");
std::cout << std::endl;
return 0;
}
Of course, now you have two problems.
当然,现在你有两个问题。
回答by gregko
I found the replace functions given in previous answers, all using in-place str.replace() call internally, very slow when working with a string of about 2 MB length. Specifically, I called something like ReplaceAll(str, "\r", ""), and on my particular device, with the text file containing a lot of newlines, it took about 27 seconds. I then replaced it with function just concatenating sub-strings in a new copy, and it took only about 1 seconds. Here is my version of ReplaceAll():
我发现之前的答案中给出的替换函数,都在内部使用就地 str.replace() 调用,在处理大约 2 MB 长度的字符串时非常慢。具体来说,我调用了 ReplaceAll(str, "\r", "") 之类的东西,在我的特定设备上,文本文件包含很多换行符,大约需要 27 秒。然后,我将其替换为仅在新副本中连接子字符串的函数,只用了大约 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;
}
Greg
格雷格
回答by Fukinagashi
Try this:
尝试这个:
#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;
}