在C++中,我该如何使用哪些函数将字符串中的子字符串替换为另一个子字符串?
eg: string test = "abc def abc def";
test.replace("abc", "hij").replace("def", "klm"); //replace occurrence of abc and def with other substring
在C++中,我该如何使用哪些函数将字符串中的子字符串替换为另一个子字符串?
eg: string test = "abc def abc def";
test.replace("abc", "hij").replace("def", "klm"); //replace occurrence of abc and def with other substring
在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"); // replace 'def' -> 'klm'
// test = "abc klm abc klm"
std:regex
解释不同的情况,比如 std::regex_replace(test, std::regex("."), "klm")
... - Thomas Vincentstd::regex("\.json")
,否则(几乎)任何以“json”结尾的子字符串也将被替换。这是因为在正则表达式中,“.”表示(几乎)任何字符... - Thomas Vincentstd::regex("\\.json")
- Danvil在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;
}
index
增加了插入到字符串中的字符串的长度。在这个特定的例子中——用"def"
替换"abc"
——这实际上是不必要的。然而,在一个更普遍的情况下,跳过刚刚被替换的字符串是很重要的。例如,如果你想用"abcabc"
替换"abc"
,而不跳过新替换的字符串段,这段代码会持续替换新替换的字符串的部分,直到内存耗尽。独立地说,跳过这些新字符可能会稍微快一点,因为这样做可以节省一些时间和string::find
函数的努力。index
)推进到已替换的字符串部分之后。 - Tim R.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"
);
}
str.replace(str.find(str2),str2.length(),str3);
这里的情况是:
str
是基本字符串str2
是要查找的子字符串str3
是替换用的子字符串我认为,如果替换字符串的长度与待替换的字符串的长度不同,那么所有解决方案都会失败。(搜索"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 );
}
}
替换子字符串并不难。
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;
}
如果您需要更好的性能,这里有一个经过优化的函数,它会修改输入的字符串而不会创建字符串的副本:
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();
}
}
测试:
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 modified: abc abc def
ReplaceStringInPlace() input string modified: a?? a?? def
if (search.empty()) { return; }
来避免传递空的 'search' 时出现无限循环。 - iOS-programmerstd::string replace(std::string str, std::string substr1, std::string substr2)
{
for (size_t index = str.find(substr1, 0); index != std::string::npos && substr1.length(); index = str.find(substr1, index + substr2.length() ) )
str.replace(index, substr1.length(), substr2);
return str;
}
不需要任何额外库的简短解决方案。
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;
}
由于它不是 string
类的成员,因此它不允许像您的示例那样漂亮的语法,但以下代码将达到相同的效果:
test = string_replace( string_replace( test, "abc", "hij"), "def", "klm")
如果您确定字符串中包含所需的子字符串,则将其替换为第一个出现的"abc"
,并替换为"hij"
test.replace( test.find("abc"), 3, "hij");
如果你的测试中没有“abc”,它将崩溃,因此请谨慎使用。
继承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 );
}
}
}
oldString
和newString
都变成const
参数。 - Ron Burk