C++ 如何替换字符串中所有出现的字符?

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

How to replace all occurrences of a character in string?

c++algorithmstr-replacestdstring

提问by big-z

What is the effective way to replace all occurrences of a character with another character in std::string?

用另一个字符替换所有出现的字符的有效方法是什么std::string

回答by Kirill V. Lyadvinsky

std::stringdoesn't contain such function but you could use stand-alone replacefunction from algorithmheader.

std::string不包含这样的功能,但你可以使用replace来自algorithm标题的独立功能。

#include <algorithm>
#include <string>

void some_func() {
  std::string s = "example string";
  std::replace( s.begin(), s.end(), 'x', 'y'); // replace all 'x' to 'y'
}

回答by UncleZeiv

I thought I'd toss in the boost solutionas well:

我想我也会加入boost 解决方案

#include <boost/algorithm/string/replace.hpp>

// in place
std::string in_place = "blah#blah";
boost::replace_all(in_place, "#", "@");

// copy
const std::string input = "blah#blah";
std::string output = boost::replace_all_copy(input, "#", "@");

回答by Gauthier Boaglio

The question is centered on characterreplacement, but, as I found this page very useful (especially Konrad's remark), I'd like to share this more generalized implementation, which allows to deal with substringsas well:

问题集中在character替换上,但是,因为我发现这个页面非常有用(尤其是Konrad的评论),我想分享这个更通用的实现,它也允许处理substrings

std::string ReplaceAll(std::string str, const std::string& from, const std::string& to) {
    size_t start_pos = 0;
    while((start_pos = str.find(from, start_pos)) != std::string::npos) {
        str.replace(start_pos, from.length(), to);
        start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
    }
    return str;
}

Usage:

用法:

std::cout << ReplaceAll(string("Number Of Beans"), std::string(" "), std::string("_")) << std::endl;
std::cout << ReplaceAll(string("ghghjghugtghty"), std::string("gh"), std::string("X")) << std::endl;
std::cout << ReplaceAll(string("ghghjghugtghty"), std::string("gh"), std::string("h")) << std::endl;

Outputs:

输出:

Number_Of_Beans

XXjXugtXty

hhjhugthty

豆数

XXjXugtXty

哈哈



EDIT:

编辑:

The above can be implemented in a more suitable way, in case performances are of your concern, by returning nothing (void) and performing the changes directly on the string strgiven as argument, passed by addressinstead of by value. This would avoid useless and costly copy of the original string, while returning the result. Your call, then...

上面可以以更合适的方式实现,如果您关心性能,则通过不返回任何内容 ( void) 并直接对str作为参数给出的字符串执行更改,通过address而不是value传递。这将避免原始字符串的无用且昂贵的副本,同时返回结果。你的电话,然后...

Code :

代码 :

static inline void ReplaceAll2(std::string &str, const std::string& from, const std::string& to)
{
    // Same inner code...
    // No return statement
}


Hope this will be helpful for some others...

希望这对其他人有帮助......

回答by minastaros

Imagine a large binary blob where all 0x00 bytes shall be replaced by "\1\x30" and all 0x01 bytes by "\1\x31" because the transport protocol allows no \0-bytes.

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

In cases where:

在以下情况下:

  • the replacing and the to-replaced string have different lengths,
  • there are many occurences of the to-replaced string within the source string and
  • the source string is large,
  • 替换字符串和要替换字符串的长度不同,
  • 源字符串中有很多次要替换的字符串,并且
  • 源字符串很大,

the provided solutions cannot be applied (because they replace only single characters) or have a performance problem, because they would call string::replace several times which generates copies of the size of the blob over and over. (I do not know the boost solution, maybe it is OK from that perspective)

提供的解决方案无法应用(因为它们只替换单个字符)或存在性能问题,因为它们会多次调用 string::replace ,这会一遍又一遍地生成 blob 大小的副本。(我不知道 boost 解决方案,也许从这个角度来看还可以)

This one walks along all occurrences in the source string and builds the new string piece by piece once:

这一个沿源字符串中所有出现的散步和建立一块新的字符串件一次

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

回答by T.E.D.

A simple find and replace for a single character would go something like:

单个字符的简单查找和替换将类似于:

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

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

To do this for the whole string, the easy thing to do would be to loop until your s.findstarts returning npos. I suppose you could also catch range_errorto exit the loop, but that's kinda ugly.

要对整个字符串执行此操作,最简单的方法是循环直到您s.find开始返回npos. 我想你也可以 catchrange_error退出循环,但这有点难看。

回答by Volomike

If you're looking to replace more than a single character, and are dealing only with std::string, then this snippet would work, replacing sNeedle in sHaystack with sReplace, and sNeedle and sReplace do not need to be the same size. This routine uses the while loop to replace all occurrences, rather than just the first one found from left to right.

如果您希望替换多个字符,并且只处理std::string,那么此代码段将起作用,将 sHaystack 中的 sNeedle 替换为 sReplace,并且 sNeedle 和 sReplace 不需要具有相同的大小。此例程使用 while 循环替换所有出现的内容,而不仅仅是从左到右找到的第一个。

while(sHaystack.find(sNeedle) != std::string::npos) {
  sHaystack.replace(sHaystack.find(sNeedle),sNeedle.size(),sReplace);
}

回答by Konrad

As Kirill suggested, either use the replace method or iterate along the string replacing each char independently.

正如 Kirill 建议的那样,要么使用替换方法,要么沿着字符串迭代独立地替换每个字符。

Alternatively you can use the findmethod or find_first_ofdepending on what you need to do. None of these solutions will do the job in one go, but with a few extra lines of code you ought to make them work for you. :-)

或者,您可以使用该find方法或find_first_of取决于您需要做什么。这些解决方案都不能一次性完成这项工作,但是通过添加几行额外的代码,您应该可以让它们为您服务。:-)

回答by Lloydie

#include <iostream>
#include <string>
using namespace std;
// Replace function..
string replace(string word, string target, string replacement){
    int len, loop=0;
    string nword="", let;
    len=word.length();
    len--;
    while(loop<=len){
        let=word.substr(loop, 1);
        if(let==target){
            nword=nword+replacement;
        }else{
            nword=nword+let;
        }
        loop++;
    }
    return nword;

}
//Main..
int main() {
  string word;
  cout<<"Enter Word: ";
  cin>>word;
  cout<<replace(word, "x", "y")<<endl;
  return 0;
}

回答by hotblack944

What about Abseil StrReplaceAll? From the header file:

怎么样绕绳下降StrReplaceAll?从头文件:

// This file defines `absl::StrReplaceAll()`, a general-purpose string
// replacement function designed for large, arbitrary text substitutions,
// especially on strings which you are receiving from some other system for
// further processing (e.g. processing regular expressions, escaping HTML
// entities, etc.). `StrReplaceAll` is designed to be efficient even when only
// one substitution is being performed, or when substitution is rare.
//
// If the string being modified is known at compile-time, and the substitutions
// vary, `absl::Substitute()` may be a better choice.
//
// Example:
//
// std::string html_escaped = absl::StrReplaceAll(user_input, {
//                                                {"&", "&amp;"},
//                                                {"<", "&lt;"},
//                                                {">", "&gt;"},
//                                                {"\"", "&quot;"},
//                                                {"'", "&#39;"}});

回答by Iván Rodríguez

Old School :-)

老套 :-)

std::string str = "H:/recursos/audio/youtube/libre/falta/"; 

for (int i = 0; i < str.size(); i++) {
    if (str[i] == '/') {
        str[i] = '\';
    }
}

std::cout << str;

Result:

结果:

H:\recursos\audio\youtube\libre\falta\

H:\recursos\audio\youtube\libre\falta\