将所有出现的角色替换为另一个角色的有效方法是什么std::string
?
std::string
不包含此类功能,但您可以使用标头中的独立replace
功能algorithm
.
#include#include void some_func() { std::string s = "example string"; std::replace( s.begin(), s.end(), 'x', 'y'); // replace all 'x' to 'y' }
我以为我也会在增强解决方案中投入:
#include// 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, "#", "@");
问题集中在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; }
用法:
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;
输出:
Number_Of_Beans
XXjXugtXty
hhjhugthty
编辑:
上面的内容可以通过更合适的方式实现,如果您需要考虑性能,可以返回nothing(void
)并直接对str
作为参数给出的字符串执行更改,通过地址而不是值传递.这将避免原始字符串的无用且昂贵的副本,同时返回结果.你的电话,然后......
代码:
static inline void ReplaceAll2(std::string &str, const std::string& from, const std::string& to) { // Same inner code... // No return statement }
希望这对其他人有帮助......
想象一个大的二进制blob,其中所有0x00字节将被"\ 1\x30"替换,所有0x01字节将被"\ 1\x31"替换,因为传输协议不允许\ 0-bytes.
如果:
替换和替换字符串有不同的长度,
源字符串中有很多被替换字符串的出现
源字符串很大,
提供的解决方案无法应用(因为它们只替换单个字符)或存在性能问题,因为它们会多次调用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); }
对单个字符的简单查找和替换将类似于:
s.replace(s.find("x"), 1, "y")
要对整个字符串执行此操作,最简单的方法是循环直到s.find
开始返回npos
.我想你也可以赶上range_error
退出循环,但这有点难看.
如果你想要替换多个单个字符,并且只处理std::string
,那么这个片段就可以了,用sReplace替换sHaystack中的sNeedle,sNeedle和sReplace不需要大小相同.此例程使用while循环替换所有出现,而不是仅从左到右找到的第一个出现.
while(sHaystack.find(sNeedle) != std::string::npos) {
sHaystack.replace(sHaystack.find(sNeedle),sNeedle.size(),sReplace);
}