在 std::string
中,替换所有出现的字符为另一个字符有哪些有效的方法?
在 std::string
中,替换所有出现的字符为另一个字符有哪些有效的方法?
std::string
没有包含这样的函数,但您可以使用来自algorithm
头文件的独立的replace
函数。
#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'
}
std::string::replace()
иҖҢдёҚжҳҜstd::replace()
жүҖеҸ‘з”ҹзҡ„жғ…еҶөпјҒ 'x' (char
)иў«йҡҗејҸиҪ¬жҚўдёә size_t
еҖј[еҖјдёә120]пјҢеӣ жӯӨж•ҙдёӘеӯ—з¬ҰдёІжҲ–е…¶дёӯдёҖйғЁеҲҶе°Ҷиў«еЎ«е……дёә120дёӘ'y'зҡ„еүҜжң¬гҖӮ - IBue这个问题的重点是字符替换,但我发现这个页面非常有用(特别是Konrad的评论),所以我想分享这个更通用的实现,它可以处理子字符串
:
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
编辑:
如果您关心性能,可以以更合适的方式实现上述操作,通过直接修改传递的字符串参数str
(通过引用而不是值传递)来进行“就地”更改。这样可以避免对原始字符串进行额外的昂贵复制。
代码:
static inline void ReplaceAll2(std::string &str, const std::string& from, const std::string& to)
{
// Same inner code...
// No return statement
}
希望这对其他人有所帮助...from
字符串是否为空,否则会导致无限循环。 - newbie#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, "#", "@");
假设有一个大的二进制 blob,其中所有的 0x00 字节都将被替换为 "\1\x30",所有的 0x01 字节都将被替换为 "\1\x31",因为传输协议不允许出现 \0 字节。
在以下情况下:
提供的解决方案无法应用(因为它们仅替换单个字符),或者存在性能问题,因为它们会多次调用 string::replace 从而生成大小与 blob 相同的副本。(我不知道 Boost 的解决方案,也许从这个角度来看是可行的)
此解决方案沿着源字符串中的所有出现并逐个构建新字符串。
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);
}
newString.append(source, lastPos, source.length() - lastPos);
而不是newString += source.substr(lastPos);
以避免创建临时字符串[因为substr()
会创建临时字符串]。(我无法编辑此答案,因为建议的编辑队列已满。) - tav对于单个字符的简单查找和替换,可以采用以下方式:
s.replace(s.find("x"), 1, "y")
要对整个字符串执行此操作,最简单的方法是循环直到s.find
开始返回npos
。我想你也可以捕获range_error
以退出循环,但那样有点丑陋。
{
字符。 我不知道“双括号”是什么。 也许你有某种字体问题? - T.E.D.为了完整起见,以下是使用std::regex
进行操作的方法。
#include <regex>
#include <string>
int main()
{
const std::string s = "example string";
const std::string r = std::regex_replace(s, std::regex("x"), "y");
}
std::string
,则此代码段将起作用,它可以将 sHaystack 中的 sNeedle 替换为 sReplace,而且 sNeedle 和 sReplace 的大小不需要相同。此例程使用 while 循环来替换所有出现次数,而不仅仅是从左到右找到第一个。while(sHaystack.find(sNeedle) != std::string::npos) {
sHaystack.replace(sHaystack.find(sNeedle),sNeedle.size(),sReplace);
}
关于 Abseil 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, {
// {"&", "&"},
// {"<", "<"},
// {">", ">"},
// {"\"", """},
// {"'", "'"}});
老派的风格 :-)
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;
结果:
H:\资源\音频\YouTube\自由\缺少\