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
How to replace all occurrences of a character in string?
提问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::string
doesn't contain such function but you could use stand-alone replace
function from algorithm
header.
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 character
replacement, 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 substrings
as 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 str
given 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.find
starts returning npos
. I suppose you could also catch range_error
to 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 find
method or find_first_of
depending 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, {
// {"&", "&"},
// {"<", "<"},
// {">", ">"},
// {"\"", """},
// {"'", "'"}});
回答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\