如何替换字符串中字符的所有出现?
-
04-10-2019 - |
题
用另一个角色替换所有角色的所有出现的有效方法是什么 std::string
?
解决方案
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'
}
其他提示
我以为我会把 提升解决方案 也:
#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, "#", "@");
这个问题集中在 character
替换,但是,正如我发现此页面非常有用的那样(尤其是 康拉德说的),我想分享这个更广泛的实施,这允许处理 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
编辑:
以上可以以更合适的方式实施,以防万一表演不关心,没有归还(void
)并直接在字符串上执行更改 str
作为参数,通过了 通过地址 代替 按价值. 。在返回结果时,这将避免原始字符串的无用且昂贵的副本。然后...
代码 :
static inline void ReplaceAll2(std::string &str, const std::string& from, const std::string& to)
{
// Same inner code...
// No return statement
}
希望这对其他人有帮助...
想象一个大的二进制斑点,其中所有0x00字节应替换为“ 1 x30”,而所有0x01字节则由“ 1 x31”代替,因为传输协议不允许 0-bytes。
在以下情况下:
- 替换和重取过的字符串具有不同的长度,
- 源字符串和
- 源字符串很大,
提供的解决方案无法应用(因为它们仅替换单个字符)或存在性能问题,因为他们会调用String ::替换几次,从而一遍又一遍地生成斑点大小的副本。 (我不知道提升解决方案,也许从这个角度可以)
这个人沿着源字符串中的所有事件行走,并逐步构建新的弦乐 一次:
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不需要相同的尺寸。该例程使用WAIL循环替换所有发生的事件,而不仅仅是从左到右发现的第一个循环。
while(sHaystack.find(sNeedle) != std::string::npos) {
sHaystack.replace(sHaystack.find(sNeedle),sNeedle.size(),sReplace);
}
正如基里尔(Kirill)所建议的那样,要么使用替换方法或沿着绳子迭代,独立替换每个炭。
或者,您可以使用 find
方法或 find_first_of
取决于您需要做的事情。这些解决方案都不会对这项工作进行,但是您应该有几行代码使它们为您工作。 :-)
#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;
}
这有效!我在书店应用程序中使用了类似的东西,其中库存存储在CSV中(例如.dat文件)。但是,在单个字符的情况下,这意味着替换器只是一个字符,例如'|',它必须以双引号为“ |”。为了不投掷无效的转换const char。
#include <iostream>
#include <string>
using namespace std;
int main()
{
int count = 0; // for the number of occurences.
// final hold variable of corrected word up to the npos=j
string holdWord = "";
// a temp var in order to replace 0 to new npos
string holdTemp = "";
// a csv for a an entry in a book store
string holdLetter = "Big Java 7th Ed,Horstman,978-1118431115,99.85";
// j = npos
for (int j = 0; j < holdLetter.length(); j++) {
if (holdLetter[j] == ',') {
if ( count == 0 )
{
holdWord = holdLetter.replace(j, 1, " | ");
}
else {
string holdTemp1 = holdLetter.replace(j, 1, " | ");
// since replacement is three positions in length,
// must replace new replacement's 0 to npos-3, with
// the 0 to npos - 3 of the old replacement
holdTemp = holdTemp1.replace(0, j-3, holdWord, 0, j-3);
holdWord = "";
holdWord = holdTemp;
}
holdTemp = "";
count++;
}
}
cout << holdWord << endl;
return 0;
}
// result:
Big Java 7th Ed | Horstman | 978-1118431115 | 99.85
我不注意的是我目前正在使用CentOS,因此我的编译器版本在下面。 C ++版本(G ++),C ++ 98默认值:
g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
如果您愿意使用 std::string
S,您可以使用此示例应用 strsub
尽可能函数,如果您希望它采用其他类型或一组参数以实现大致相同的目标。基本上,它使用的属性和功能 std::string
快速删除匹配的字符集,并直接在该字符中插入所需字符 std::string
. 。每次进行此替换操作时,如果仍然可以找到匹配的字符替换,则偏移更新,如果不能更换它,则它将从最后一个更新中返回其状态中的字符串。
#include <iostream>
#include <string>
std::string strsub(std::string stringToModify,
std::string charsToReplace,
std::string replacementChars);
int main()
{
std::string silly_typos = "annoiiyyyng syyyllii tiipos.";
std::cout << "Look at these " << silly_typos << std::endl;
silly_typos = strsub(silly_typos, "yyy", "i");
std::cout << "After a little elbow-grease, a few less " << silly_typos << std::endl;
silly_typos = strsub(silly_typos, "ii", "y");
std::cout << "There, no more " << silly_typos << std::endl;
return 0;
}
std::string strsub(std::string stringToModify,
std::string charsToReplace,
std::string replacementChars)
{
std::string this_string = stringToModify;
std::size_t this_occurrence = this_string.find(charsToReplace);
while (this_occurrence != std::string::npos)
{
this_string.erase(this_occurrence, charsToReplace.size());
this_string.insert(this_occurrence, replacementChars);
this_occurrence = this_string.find(charsToReplace,
this_occurrence + replacementChars.size());
}
return this_string;
}
如果您不想依靠 std::string
s作为您的参数,因此您可以通过C风格字符串传递,您可以在下面看到更新的示例:
#include <iostream>
#include <string>
std::string strsub(const char * stringToModify,
const char * charsToReplace,
const char * replacementChars,
uint64_t sizeOfCharsToReplace,
uint64_t sizeOfReplacementChars);
int main()
{
std::string silly_typos = "annoiiyyyng syyyllii tiipos.";
std::cout << "Look at these " << silly_typos << std::endl;
silly_typos = strsub(silly_typos.c_str(), "yyy", "i", 3, 1);
std::cout << "After a little elbow-grease, a few less " << silly_typos << std::endl;
silly_typos = strsub(silly_typos.c_str(), "ii", "y", 2, 1);
std::cout << "There, no more " << silly_typos << std::endl;
return 0;
}
std::string strsub(const char * stringToModify,
const char * charsToReplace,
const char * replacementChars,
uint64_t sizeOfCharsToReplace,
uint64_t sizeOfReplacementChars)
{
std::string this_string = stringToModify;
std::size_t this_occurrence = this_string.find(charsToReplace);
while (this_occurrence != std::string::npos)
{
this_string.erase(this_occurrence, sizeOfCharsToReplace);
this_string.insert(this_occurrence, replacementChars);
this_occurrence = this_string.find(charsToReplace,
this_occurrence + sizeOfReplacementChars);
}
return this_string;
}
对于简单的情况,这种情况非常有效,而无需使用任何其他库,然后使用STD :: String(已在使用中)。
替换所有角色的出现 一种 有性格 b 在 Some_string:
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
老套 :-)
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: rocursos audio youtube libre falta