C++ 如何在标准字符串中搜索/查找和替换?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1494399/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 20:11:41  来源:igfitidea点击:

How do I Search/Find and Replace in a standard string?

c++replacestd

提问by Adam Tegen

Is there a way to replace all occurrences of a substring with another string in std::string?

有没有办法用另一个字符串替换所有出现的子字符串std::string

For instance:

例如:

void SomeFunction(std::string& str)
{
   str = str.replace("hello", "world"); //< I'm looking for something nice like this
}

采纳答案by yves Baumes

Why not implement your own replace?

为什么不实现自己的替换?

void myReplace(std::string& str,
               const std::string& oldStr,
               const std::string& newStr)
{
  std::string::size_type pos = 0u;
  while((pos = str.find(oldStr, pos)) != std::string::npos){
     str.replace(pos, oldStr.length(), newStr);
     pos += newStr.length();
  }
}

回答by ilyaigpetrov

#include <boost/algorithm/string.hpp> // include Boost, a C++ library
...
std::string target("Would you like a foo of chocolate. Two foos of chocolate?");
boost::replace_all(target, "foo", "bar");

Here is the official documentationon replace_all.

这是关于 replace_all的官方文档

回答by nobar

In C++11, you can do this as a one-liner with a call to regex_replace:

在 C++11 中,您可以将其作为单行调用来执行此操作regex_replace

#include <string>
#include <regex>

using std::string;

string do_replace( string const & in, string const & from, string const & to )
{
  return std::regex_replace( in, std::regex(from), to );
}

string test = "Remove all spaces";
std::cout << do_replace(test, " ", "") << std::endl;

output:

输出:

Removeallspaces

回答by Czarek Tomczak

Why not return a modified string?

为什么不返回修改后的字符串?

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 Marius

My templatized inline in-place find-and-replace:

我的模板化内联就地查找和替换:

template<class T>
int inline findAndReplace(T& source, const T& find, const T& replace)
{
    int num=0;
    typename T::size_t fLen = find.size();
    typename T::size_t rLen = replace.size();
    for (T::size_t pos=0; (pos=source.find(find, pos))!=T::npos; pos+=rLen)
    {
        num++;
        source.replace(pos, fLen, replace);
    }
    return num;
}

It returns a count of the number of items substituted (for use if you want to successively run this, etc). To use it:

它返回替换项目数的计数(用于如果您想连续运行它等)。要使用它:

std::string str = "one two three";
int n = findAndReplace(str, "one", "1");

回答by Adam Tegen

I believe this would work. It takes const char*'s as a parameter.

我相信这会奏效。它以 const char* 作为参数。

//params find and replace cannot be NULL
void FindAndReplace( std::string& source, const char* find, const char* replace )
{
   //ASSERT(find != NULL);
   //ASSERT(replace != NULL);
   size_t findLen = strlen(find);
   size_t replaceLen = strlen(replace);
   size_t pos = 0;

   //search for the next occurrence of find within source
   while ((pos = source.find(find, pos)) != std::string::npos)
   {
      //replace the found string with the replacement
      source.replace( pos, findLen, replace );

      //the next line keeps you from searching your replace string, 
      //so your could replace "hello" with "hello world" 
      //and not have it blow chunks.
      pos += replaceLen; 
   }
}

回答by Alan

The easiest way (offering something near what you wrote) is to use Boost.Regex, specifically regex_replace.

最简单的方法(提供接近你写的东西)是使用Boost.Regex,特别是regex_replace

std::string has built in find() and replace() methods, but they are more cumbersome to work with as they require dealing with indices and string lengths.

std::string 内置了 find() 和 replace() 方法,但它们使用起来更麻烦,因为它们需要处理索引和字符串长度。

回答by Bj?rn Ganster

// Replace all occurrences of searchStr in str with replacer
// Each match is replaced only once to prevent an infinite loop
// The algorithm iterates once over the input and only concatenates 
// to the output, so it should be reasonably efficient
std::string replace(const std::string& str, const std::string& searchStr, 
    const std::string& replacer)
{
    // Prevent an infinite loop if the input is empty
    if (searchStr == "") {
        return str;
    }

    std::string result = "";
    size_t pos = 0;
    size_t pos2 = str.find(searchStr, pos);

    while (pos2 != std::string::npos) {
        result += str.substr(pos, pos2-pos) + replacer;
        pos = pos2 + searchStr.length();
        pos2 = str.find(searchStr, pos);
    }

    result += str.substr(pos, str.length()-pos);
    return result;
}

回答by ericcurtin

#include <string>

using std::string;

void myReplace(string& str,
               const string& oldStr,
               const string& newStr) {
  if (oldStr.empty()) {
    return;
  }

  for (size_t pos = 0; (pos = str.find(oldStr, pos)) != string::npos;) {
    str.replace(pos, oldStr.length(), newStr);
    pos += newStr.length();
  }
}

The check for oldStr being empty is important. If for whatever reason that parameter is empty you will get stuck in an infinite loop.

检查 oldStr 是否为空很重要。如果由于某种原因该参数为空,您将陷入无限循环。

But yeah use the tried and tested C++11 or Boost solution if you can.

但是,如果可以,请使用久经考验的 C++11 或 Boost 解决方案。