什么是有效的方法来取代一个字符的所有出现与另一个字符在std::字符串?


当前回答

这不是标准库中缺少的唯一方法,它本来是低级别的。 这个用例和许多其他用例由通用库涵盖,例如:

波科 绳降 提高 QtCore

QtCore & QString有我的偏好:它支持UTF8,使用更少的模板,这意味着可以理解的错误和更快的编译。它使用了“q”前缀,使命名空间变得不必要,并简化了头文件。 Boost经常生成可怕的错误消息和缓慢的编译时间。 POCO似乎是一种合理的妥协。

其他回答

我想我会使用std::replace_if()

一个简单的字符替换程序(OP要求的)可以使用标准库函数编写。

就地版本:

#include <string>
#include <algorithm>

void replace_char(std::string& in,
                  std::string::value_type srch,
                  std::string::value_type repl)
{
    std::replace_if(std::begin(in), std::end(in),
                    [&srch](std::string::value_type v) { return v==srch; },
                    repl);
    return;
}

如果输入是const字符串,则返回一个副本的重载:

std::string replace_char(std::string const& in,
                         std::string::value_type srch,
                         std::string::value_type repl)
{
    std::string result{ in };
    replace_char(result, srch, repl);
    return result;
}

一个简单的查找和替换单个字符是这样的:

s.find("x"), 1, "y")

要对整个字符串执行此操作,最简单的方法是循环,直到s.find开始返回npos。我认为您还可以捕获range_error来退出循环,但这有点丑陋。

想象一个大的二进制blob,其中所有0x00字节都应该被“\1\x30”取代,所有0x01字节都应该被“\1\x31”取代,因为传输协议不允许有0字节。

在以下情况下:

被替换的字符串和被替换的字符串长度不同, 要替换的字符串在源字符串和中多次出现 源字符串很大,

所提供的解决方案不能应用(因为它们只替换单个字符),或者存在性能问题,因为它们会多次调用string::replace,从而反复生成blob大小的副本。 (我不知道提升方案,也许从这个角度来看是可以的)

这个函数遍历源字符串中出现的所有事件,并一次逐条构建新字符串:

void replaceAll(std::string& source, const std::string& from, const std::string& to)
{
    std::string newString;
    newString.reserve(source.length());  // avoids a few memory allocations

    std::string::size_type lastPos = 0;
    std::string::size_type findPos;

    while(std::string::npos != (findPos = source.find(from, lastPos)))
    {
        newString.append(source, lastPos, findPos - lastPos);
        newString += to;
        lastPos = findPos + from.length();
    }

    // Care for the rest after last occurrence
    newString += source.substr(lastPos);

    source.swap(newString);
}

如何替换任何字符串与任何字符串仅使用良好的旧C字符串函数?

char original[256]="First Line\nNext Line\n", dest[256]="";
char* replace_this = "\n"; // this is now a single character but could be any string
char* with_this = "\r\n"; // this is 2 characters but could be of any length

/* get the first token */
char* token = strtok(original, replace_this);

/* walk through other tokens */
while (token != NULL) {
    strcat(dest, token);
    strcat(dest, with_this);
    token = strtok(NULL, replace_this);
}

Dest现在应该有我们要找的东西了。

对于简单的情况,无需使用任何其他库就可以很好地工作,然后使用std::string(已经在使用)。

将some_string中出现的所有字符a替换为字符b:

for (size_t i = 0; i < some_string.size(); ++i) {
    if (some_string[i] == 'a') {
        some_string.replace(i, 1, "b");
    }
}

如果字符串很大,或者有多个需要替换的调用,您可以应用这个答案中提到的技术:https://stackoverflow.com/a/29752943/3622300