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

时间:2011-01-10 03:42:10

标签: 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

17 个答案:

答案 0 :(得分:63)

C ++中没有一个内置函数可以做到这一点。如果您想将一个子字符串的所有实例替换为另一个子字符串,可以通过混合调用string::findstring::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增加了插入字符串的字符串的长度。在此特定示例中 - 将"abc"替换为"def" - 这实际上不是必需的。但是,在更一般的设置中,跳过刚刚替换的字符串非常重要。例如,如果要将"abc"替换为"abcabc",而不跳过新替换的字符串段,则此代码将持续替换部分新替换的字符串,直到内存耗尽为止。无论如何,跳过这些新角色可能会稍微快一些,因为这样做可以节省string::find函数的时间和精力。

希望这有帮助!

答案 1 :(得分:57)

Boost String Algorithms Library方式:

#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"
  );
}

答案 2 :(得分:35)

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

答案 3 :(得分:29)

在C ++ 11中,您可以使用UICollectionViewDelegateFlowLayout

regex_replace

答案 4 :(得分:25)

str.replace(str.find(str2),str2.length(),str3);

其中

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

答案 5 :(得分:15)

替换子串不应该那么难。

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

答案 6 :(得分:5)

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")

答案 7 :(得分:2)

如果您确定字符串中存在必需的子字符串,那么这将替换"abc""hij"

的第一次出现
test.replace( test.find("abc"), 3, "hij");

如果你在测试中没有“abc”,它会崩溃,所以要小心使用它。

答案 8 :(得分:2)

概括了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 );
    }
  }
}

答案 9 :(得分:1)

这是我使用构建器策略编写的解决方案:

#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());
}

测试:

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);

}

答案 10 :(得分:0)

@Czarek Tomczak提供的版本。
同时允许std::stringstd::wstring

template <typename charType>
void ReplaceSubstring(std::basic_string<charType>& subject,
    const std::basic_string<charType>& search,
    const std::basic_string<charType>& replace)
{
    if (search.empty()) { return; }
    typename std::basic_string<charType>::size_type pos = 0;
    while((pos = subject.find(search, pos)) != std::basic_string<charType>::npos) {
         subject.replace(pos, search.length(), replace);
         pos += replace.length();
    }
}

答案 11 :(得分:0)

    string & replace(string & subj, string old, string neu)
    {
        size_t uiui = subj.find(old);
        if (uiui != string::npos)
        {
           subj.erase(uiui, old.size());
           subj.insert(uiui, neu);
        }
        return subj;
    }

我认为这很少符合您的要求!

答案 12 :(得分:0)

std::string replace(const std::string & in
                  , const std::string & from
                  , const std::string & to){
  if(from.size() == 0 ) return in;
  std::string out = "";
  std::string tmp = "";
  for(int i = 0, ii = -1; i < in.size(); ++i) {
    // change ii
    if     ( ii <  0 &&  from[0] == in[i] )  {
      ii  = 0;
      tmp = from[0]; 
    } else if( ii >= 0 && ii < from.size()-1 )  {
      ii ++ ;
      tmp = tmp + in[i];
      if(from[ii] == in[i]) {
      } else {
        out = out + tmp;
        tmp = "";
        ii = -1;
      }
    } else {
      out = out + in[i];
    }
    if( tmp == from ) {
      out = out + to;
      tmp = "";
      ii = -1;
    }
  }
  return out;
};

答案 13 :(得分:0)

这是一个使用递归的解决方案,它将所有出现的子字符串替换为另一个子字符串。无论字符串的大小如何,这都有效。

std::string ReplaceString(const std::string source_string, const std::string old_substring, const std::string new_substring)
{
    // Can't replace nothing.
    if (old_substring.empty())
        return source_string;

    // Find the first occurrence of the substring we want to replace.
    size_t substring_position = source_string.find(old_substring);

    // If not found, there is nothing to replace.
    if (substring_position == std::string::npos)
        return source_string;

    // Return the part of the source string until the first occurance of the old substring + the new replacement substring + the result of the same function on the remainder.
    return source_string.substr(0,substring_position) + new_substring + ReplaceString(source_string.substr(substring_position + old_substring.length(),source_string.length() - (substring_position + old_substring.length())), old_substring, new_substring);
}

用法示例:

std::string my_cpp_string = "This string is unmodified. You heard me right, it's unmodified.";
std::cout << "The original C++ string is:\n" << my_cpp_string << std::endl;
my_cpp_string = ReplaceString(my_cpp_string, "unmodified", "modified");
std::cout << "The final C++ string is:\n" << my_cpp_string << std::endl;

答案 14 :(得分:0)

size_t index = 0;
std::string str = "T X T", substr1=" " /*To replace*/, substr2="-" /*replace with this*/;
for (index = str.find(substr1, index); index != std::string::npos; index = str.find(substr1, index + strlen(substr1.c_str())) )
    str.replace(index, strlen(substr1.c_str()), substr2);

答案 15 :(得分:0)

std::string replace(std::string str, const std::string& sub1, const std::string& sub2)
{
    if (sub1.empty())
        return str;

    std::size_t pos;
    while ((pos = str.find(sub1)) != std::string::npos)
        str.replace(pos, sub1.size(), sub2);

    return str;
}

答案 16 :(得分:0)

#include <string>

首先:

void replace_first(std::string& text, const std::string& from,
   const std::string& to)
{
    const auto at = text.find(from, 0);

    if (at != std::string::npos)
        text.replace(at, from.length(), to);
}

全部:

void replace_all(std::string& text, const std::string& from,
   const std::string& to)
{
    for (auto at = text.find(from, 0); at != std::string::npos;
        at = text.find(from, at + to.length()))
    {
        text.replace(at, from.length(), to);
    }
}

计数:

size_t replace_count(std::string& text,
   const std::string& from, const std::string& to)
{
    size_t count = 0;

    for (auto at = text.find(from, 0); at != std::string::npos;
        at = text.find(from, at + to.length()))
    {
        ++count;
        text.replace(at, from.length(), to);
    }

    return count;
}

复制:

std::string replace_all_copy(const std::string& text,
   const std::string& from, const std::string& to)
{
    auto copy = text;
    replace_all(copy, from, to);
    return copy;
}
相关问题