用另一个子串C++替换substring

Ste*_*eng 79 c++ string replace 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
Run Code Online (Sandbox Code Playgroud)

tem*_*def 67

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;
}
Run Code Online (Sandbox Code Playgroud)

在这段代码的最后一行,我增加index了插入字符串的字符串的长度.在这个特定的例子中 - 替换"abc""def"- 这实际上不是必需的.但是,在更一般的设置中,跳过刚刚替换的字符串非常重要.例如,如果要替换"abc""abcabc",而不跳过新替换的字符串段,则此代码将持续替换部分新替换的字符串,直到内存耗尽为止.独立地,无论如何跳过这些新角色可能稍快一些,因为这样做可以节省一些时间和精力string::find.

希望这可以帮助!

  • 我不相信你需要增加索引,因为你已经替换了数据,所以无论如何都不会提取它. (6认同)
  • @蒂姆。你是对的,我是在回应 rossb83,他说索引的增量是不必要的。只是想防止错误信息。所以对于其他人:**将索引增加替换字符串的长度**(在这种情况下为 3)** 是必要的**。不要从代码示例中删除它。 (2认同)

Ole*_*nko 61

Boost String Algorithms Library way:

#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"
  );
}
Run Code Online (Sandbox Code Playgroud)

  • Boost主要是一种矫枉过正。 (3认同)
  • 周杰伦 我需要提升以替换所有子字符串。 (2认同)
  • 我觉得很有趣的是,C++ 问题的答案中的“大量”部分都有一个使用 boost 的简单、简洁的答案,并且“其中每一个”都附加了“boost 是矫枉过正”的注释。我无法想象使用 C++ *没有* boost... (2认同)

小智 38

我认为如果替换字符串的长度与要替换的字符串的长度不同,则所有解决方案都将失败.(搜索"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 );
    }
}
Run Code Online (Sandbox Code Playgroud)


Jin*_*Yao 36

在C++ 11中,您可以使用regex_replace:

string test = "abc def abc def";
test = regex_replace(test, regex("def"), "klm");
Run Code Online (Sandbox Code Playgroud)

  • 小心,这不能很好地概括,你最终可能会传递一些 `std:regex` 解释不同的东西,如 `std::regex_replace(test, std::regex("."), "klm")` ... (5认同)
  • @阿米特我不知道它是否值得一个答案块。我想说的是,对于简单的“def”示例,它是有效的,但是如果您要替换的内容“意味着”正则表达式语法中的某些内容,您将不会获得预期的结果!例如,如果你想替换`".json"`,你必须使用`std::regex("\.json")`,否则(几乎)任何以`json`结尾的子字符串也将被替换。这是因为“.”意味着(几乎)正则表达式中的任何字符...... (5认同)
  • 如果我们有c ++ 11,这将是伟大的! (4认同)
  • #include &lt;正则表达式&gt; (2认同)

Jef*_*her 33

str.replace(str.find(str2),str2.length(),str3);
Run Code Online (Sandbox Code Playgroud)

哪里

  • str 是基本字符串
  • str2 是要查找的子字符串
  • str3 是替换子字符串

  • 这只取代了第一次出现,不是吗? (3认同)
  • 我建议确保str.find(str2)的结果不等于std :: string :: npos auto found = str.find(str2); if(found!= std :: string :: npos)str.replace(found,str2.length(),str3); (3认同)

Cza*_*zak 17

替换子串不应该那么难.

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;
}
Run Code Online (Sandbox Code Playgroud)

如果您需要性能,这里是一个修改输入字符串的优化函数,它不会创建字符串的副本:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

测试:

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;
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)


Alt*_*ems 11

std::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;
}
Run Code Online (Sandbox Code Playgroud)

您不需要任何额外的库的简短解决方案。

  • 看起来是迄今为止最优雅的答案,没有任何过度设计 (3认同)

Mic*_*urr 6

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;
}
Run Code Online (Sandbox Code Playgroud)

由于它不是string该类的成员,因此它不允许使用与示例中相同的语法,但以下内容将执行等效操作:

test = string_replace( string_replace( test, "abc", "hij"), "def", "klm")
Run Code Online (Sandbox Code Playgroud)