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

Ada*_*gen 91 c++ replace std

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

例如:

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

ily*_*rov 153

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

这是关于replace_all 的官方文档.

  • +1,有一点需要注意:对于任何版本<12.3,对于Sun Studio版本的升级> 1.43,`replace_all`都会出现段错误 (4认同)
  • @ppumkin:这意味着你的编译器(或构建设置,或其他)很糟糕,而不是目标架构,它与它无关. (4认同)
  • `boost`在嵌入式设备上大大增加了编译时间.甚至是ARMv7四核.100行代码在2分钟内编译,无需提升,2秒. (2认同)

yve*_*mes 71

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

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

  • 所有对"替换"的调用你都在用内存搞乱一点:如果从"ooooooo ... o"中删除"o",复杂性将是n².我想一个人可以做得更好,但这个解决方案的优点是易于理解. (3认同)

nob*_*bar 28

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

输出:

Removeallspaces
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这不仅适用于非常基本的字母数字字符,也不需要进行大量预处理,具体取决于字符串的类型.我还没有找到一个通用的基于正则表达式的字符串替换. (2认同)

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)


Mar*_*ius 6

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

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

它返回替换项目数的计数(如果要连续运行,则使用,等等).要使用它:

std::string str = "one two three";
int n = findAndReplace(str, "one", "1");
Run Code Online (Sandbox Code Playgroud)

  • 我在GCC下尝试了这个示例,但它不会编译 - 它不喜欢使用T :: size_t.用typename T :: size_type替换T :: size_t可以解决问题. (4认同)