用另一个子字符串 C++ 替换子字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4643512/
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
Replace substring with another substring C++
提问by Steveng
How could I replace a substring in a string with another substring in C++, what functions could I use?
如何用 C++ 中的另一个子字符串替换字符串中的子字符串,我可以使用哪些函数?
eg: string test = "abc def abc def";
test.replace("abc", "hij").replace("def", "klm"); //replace occurrence of abc and def with other substring
回答by templatetypedef
There is no one built-in function in C++ to do this. If you'd like to replace all instances of one substring with another, you can do so by intermixing calls to string::find
and string::replace
. For example:
C++ 中没有一个内置函数可以做到这一点。如果您想用另一个替换一个子字符串的所有实例,您可以通过混合调用string::find
和 来实现string::replace
。例如:
size_t index = 0;
while (true) {
/* Locate the substring to replace. */
index = str.find("abc", index);
if (index == std::string::npos) break;
/* Make the replacement. */
str.replace(index, 3, "def");
/* Advance index forward so the next iteration doesn't pick it up as well. */
index += 3;
}
In the last line of this code, I've incremented index
by the length of the string that's been inserted into the string. In this particular example - replacing "abc"
with "def"
- this is not actually necessary. However, in a more general setting, it is important to skip over the string that's just been replaced. For example, if you want to replace "abc"
with "abcabc"
, without skipping over the newly-replaced string segment, this code would continuously replace parts of the newly-replaced strings until memory was exhausted. Independently, it might be slightly faster to skip past those new characters anyway, since doing so saves some time and effort by the string::find
function.
在这段代码的最后一行中,我增加index
了插入字符串的字符串长度。在这个特定的例子中 - 替换"abc"
为"def"
- 这实际上不是必需的。但是,在更一般的设置中,跳过刚刚被替换的字符串很重要。例如,如果要替换"abc"
为"abcabc"
,而不跳过新替换的字符串段,则此代码将不断替换新替换的字符串的一部分,直到内存耗尽。独立地,无论如何跳过这些新字符可能会稍微快一点,因为这样做可以节省string::find
函数的一些时间和精力。
Hope this helps!
希望这可以帮助!
回答by Oleg Svechkarenko
Boost String Algorithms Libraryway:
Boost字符串算法库方式:
#include <boost/algorithm/string/replace.hpp>
{ // 1.
string test = "abc def abc def";
boost::replace_all(test, "abc", "hij");
boost::replace_all(test, "def", "klm");
}
{ // 2.
string test = boost::replace_all_copy
( boost::replace_all_copy<string>("abc def abc def", "abc", "hij")
, "def"
, "klm"
);
}
回答by Jingguo Yao
In c++11, you can use std::regex_replace
:
在c++11 中,您可以使用std::regex_replace
:
#include <string>
#include <regex>
std::string test = "abc def abc def";
test = std::regex_replace(test, std::regex("def"), "klm");
回答by rotmax
I think all solutions will fail if the length of the replacing string is different from the length of the string to be replaced. (search for "abc" and replace by "xxxxxx") A general approach might be:
如果替换字符串的长度与要替换的字符串长度不同,我认为所有解决方案都会失败。(搜索“abc”并替换为“xxxxxx”)一般方法可能是:
void replaceAll( string &s, const string &search, const string &replace ) {
for( size_t pos = 0; ; pos += replace.length() ) {
// Locate the substring to replace
pos = s.find( search, pos );
if( pos == string::npos ) break;
// Replace by erasing and inserting
s.erase( pos, search.length() );
s.insert( pos, replace );
}
}
回答by Jeff Zacher
str.replace(str.find(str2),str2.length(),str3);
Where
在哪里
str
is the base stringstr2
is the sub string to findstr3
is the replacement substring
str
是基本字符串str2
是要查找的子字符串str3
是替换子串
回答by Czarek Tomczak
Replacing substrings should not be that hard.
替换子字符串不应该那么难。
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 an 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 modified: abc abc def
ReplaceStringInPlace() input string modified: a?? a?? def
回答by Michael Burr
using std::string;
string string_replace( string src, string const& target, string const& repl)
{
// handle error situations/trivial cases
if (target.length() == 0) {
// searching for a match to the empty string will result in
// an infinite loop
// it might make sense to throw an exception for this case
return src;
}
if (src.length() == 0) {
return src; // nothing to match against
}
size_t idx = 0;
for (;;) {
idx = src.find( target, idx);
if (idx == string::npos) break;
src.replace( idx, target.length(), repl);
idx += repl.length();
}
return src;
}
Since it's not a member of the string
class, it doesn't allow quite as nice a syntax as in your example, but the following will do the equivalent:
由于它不是string
类的成员,因此它不允许使用像您的示例中那样好的语法,但以下将执行等效操作:
test = string_replace( string_replace( test, "abc", "hij"), "def", "klm")
回答by ch0kee
If you are sure that the required substring is present in the string, then this will replace the first occurence of "abc"
to "hij"
如果您确定字符串中存在所需的子字符串,则这将替换第一次出现的"abc"
to"hij"
test.replace( test.find("abc"), 3, "hij");
It will crash if you dont have "abc" in test, so use it with care.
如果您在测试中没有“abc”,它会崩溃,因此请谨慎使用。
回答by Neoh
Generalizing on rotmax's answer, here is a full solution to search & replace all instances in a string. If both substrings are of different size, the substring is replaced using string::erase and string::insert., otherwise the faster string::replace is used.
概括 rotmax 的答案,这里有一个完整的解决方案来搜索和替换字符串中的所有实例。如果两个子串的大小不同,则使用 string::erase 和 string::insert. 替换子串,否则使用更快的 string::replace。
void FindReplace(string& line, string& oldString, string& newString) {
const size_t oldSize = oldString.length();
// do nothing if line is shorter than the string to find
if( oldSize > line.length() ) return;
const size_t newSize = newString.length();
for( size_t pos = 0; ; pos += newSize ) {
// Locate the substring to replace
pos = line.find( oldString, pos );
if( pos == string::npos ) return;
if( oldSize == newSize ) {
// if they're same size, use std::string::replace
line.replace( pos, oldSize, newString );
} else {
// if not same size, replace by erasing and inserting
line.erase( pos, oldSize );
line.insert( pos, newString );
}
}
}
回答by Den-Jason
Here is a solution I wrote using the builder tactic:
这是我使用构建器策略编写的解决方案:
#include <string>
#include <sstream>
using std::string;
using std::stringstream;
string stringReplace (const string& source,
const string& toReplace,
const string& replaceWith)
{
size_t pos = 0;
size_t cursor = 0;
int repLen = toReplace.length();
stringstream builder;
do
{
pos = source.find(toReplace, cursor);
if (string::npos != pos)
{
//copy up to the match, then append the replacement
builder << source.substr(cursor, pos - cursor);
builder << replaceWith;
// skip past the match
cursor = pos + repLen;
}
}
while (string::npos != pos);
//copy the remainder
builder << source.substr(cursor);
return (builder.str());
}
Tests:
测试:
void addTestResult (const string&& testId, bool pass)
{
...
}
void testStringReplace()
{
string source = "123456789012345678901234567890";
string toReplace = "567";
string replaceWith = "abcd";
string result = stringReplace (source, toReplace, replaceWith);
string expected = "1234abcd8901234abcd8901234abcd890";
bool pass = (0 == result.compare(expected));
addTestResult("567", pass);
source = "123456789012345678901234567890";
toReplace = "123";
replaceWith = "-";
result = stringReplace(source, toReplace, replaceWith);
expected = "-4567890-4567890-4567890";
pass = (0 == result.compare(expected));
addTestResult("start", pass);
source = "123456789012345678901234567890";
toReplace = "0";
replaceWith = "";
result = stringReplace(source, toReplace, replaceWith);
expected = "123456789123456789123456789";
pass = (0 == result.compare(expected));
addTestResult("end", pass);
source = "123123456789012345678901234567890";
toReplace = "123";
replaceWith = "-";
result = stringReplace(source, toReplace, replaceWith);
expected = "--4567890-4567890-4567890";
pass = (0 == result.compare(expected));
addTestResult("concat", pass);
source = "1232323323123456789012345678901234567890";
toReplace = "323";
replaceWith = "-";
result = stringReplace(source, toReplace, replaceWith);
expected = "12-23-123456789012345678901234567890";
pass = (0 == result.compare(expected));
addTestResult("interleaved", pass);
source = "1232323323123456789012345678901234567890";
toReplace = "===";
replaceWith = "-";
result = utils_stringReplace(source, toReplace, replaceWith);
expected = source;
pass = (0 == result.compare(expected));
addTestResult("no match", pass);
}