C++中是否可以用另一个字符串替换部分字符串?用另一个字符串替换字符串的一部分
基本上,我想这样做:
QString string("hello $name");
string.replace("$name", "Somename");
但我想用C++标准库。
C++中是否可以用另一个字符串替换部分字符串?用另一个字符串替换字符串的一部分
基本上,我想这样做:
QString string("hello $name");
string.replace("$name", "Somename");
但我想用C++标准库。
有一个函数来查找字符串(find
)内的子串,和功能上与另一个字符串(replace
)的字符串替换特定的范围内,所以可以结合使用这些得到你想要的效果:
bool replace(std::string& str, const std::string& from, const std::string& to) {
size_t start_pos = str.find(from);
if(start_pos == std::string::npos)
return false;
str.replace(start_pos, from.length(), to);
return true;
}
std::string string("hello $name");
replace(string, "$name", "Somename");
在回应评论,我觉得replaceAll
可能会是这个样子:
void replaceAll(std::string& str, const std::string& from, const std::string& to) {
if(from.empty())
return;
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(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
}
}
如果原始字符串中有多个“$ name”实例并且我想要替换所有这些实例,我将如何修复它。 – 2010-08-05 19:14:10
为什么每个'const'参考都不会传递'from'和'to'?你的函数如果'from'不在那里?从我那里得到'-1'。 – sbi 2010-08-05 19:15:53
添加一个循环并使用find()方法的“pos”参数 – 2010-08-05 19:17:08
std::string
有一个replace
方法,是你在找什么?
你可以尝试:
s.replace(s.find("$name"), sizeof("Somename")-1, "Somename");
我还没有尝试过自己,只是阅读文档上find()
和replace()
。
从我所看到的std :: string替换方法并不需要两个字符串,因为我愿意。 – 2010-08-05 19:10:04
我认为迈克尔Mrozek有一个更优雅的解决方案 – 2010-08-05 19:16:19
这不适合我。 sizeof应该用字符串(“Somename”)替换。size() - 1 – TimZaman 2014-04-10 08:34:09
是的,你可以做到这一点,但你必须找到字符串的find()成员的第一个字符串的位置,然后替换它的replace()成员。
string s("hello $name");
size_type pos = s.find("$name");
if (pos != string::npos) {
s.replace(pos, 5, "somename"); // 5 = length($name)
}
如果您在使用标准库的规划,你应该得到的书The C++ Standard Library覆盖所有这些东西很好的副本保持。
好吧,我会尝试写我自己的功能来做到这一点。 – 2010-08-05 19:11:02
它是size_t而不是size_type – revo 2013-01-08 23:54:41
它是std :: string :: size_type,而不是size_t或未经修改的size_type。 – jmucchiello 2013-05-18 16:33:55
有了新的字符串返回使用本:
std::string ReplaceString(std::string subject, const std::string& search,
const std::string& replace) {
size_t pos = 0;
while ((pos = subject.find(search, pos)) != std::string::npos) {
subject.replace(pos, search.length(), replace);
pos += replace.length();
}
return subject;
}
如果您需要的性能,这里是一个优化的函数,修改输入的字符串,它不建立一个字符串的副本:
void ReplaceStringInPlace(std::string& subject, const std::string& search,
const std::string& replace) {
size_t pos = 0;
while ((pos = subject.find(search, pos)) != std::string::npos) {
subject.replace(pos, search.length(), replace);
pos += replace.length();
}
}
测试:
std::string input = "abc abc def";
std::cout << "Input string: " << input << std::endl;
std::cout << "ReplaceString() return value: "
<< ReplaceString(input, "bc", "!!") << std::endl;
std::cout << "ReplaceString() input string not modified: "
<< input << std::endl;
ReplaceStringInPlace(input, "bc", "??");
std::cout << "ReplaceStringInPlace() input string modified: "
<< input << std::endl;
输出:
Input string: abc abc def
ReplaceString() return value: a!! a!! def
ReplaceString() input string not modified: abc abc def
ReplaceStringInPlace() input string modified: a?? a?? def
您对ReplaceStringInPlace()中的subject.replace的调用是真正修改字符串inplace吗? – Damian 2016-07-13 09:08:26
我简单地看了一下源代码,看起来它使用移动语义将旧字符串的前面移动到位,这样就不会被复制,但是新插入的内容会被复制到旧字符串中,而旧的尾部字符串被复制到缓冲的旧字符串的大小调整。有可能字符串扩展得太多,整个底层缓冲区被重新分配,但是如果你像在他的例子中一样替换1到1,我认为它确实发生了“就地”,或者没有任何复制,但是如果你扩展字符串,只有旧字符串的第一部分不会被复制,只有可能那么。 – Motes 2016-10-13 21:38:09
std::string replace(std::string base, const std::string from, const std::string to) {
std::string SecureCopy = base;
for (size_t start_pos = SecureCopy.find(from); start_pos != std::string::npos; start_pos = SecureCopy.find(from,start_pos))
{
SecureCopy.replace(start_pos, from.length(), to);
}
return SecureCopy;
}
你能解释一下这段代码吗(在你的答案中)?你可能会得到更多的赞扬! – 2014-04-17 15:04:52
我一般这样使用:
std::string& replace(std::string& s, const std::string& from, const std::string& to)
{
if(!from.empty())
for(size_t pos = 0; (pos = s.find(from, pos)) != std::string::npos; pos += to.size())
s.replace(pos, from.size(), to);
return s;
}
它反复调用std::string::find()
找到搜索字符串的其他事件,直到std::string::find()
没有发现任何东西。由于std::string::find()
返回匹配的位置,所以我们没有使迭代器无效的问题。
用C++ 11可以使用std::regex
像这样:需要转义转义字符
std::string string("hello $name");
string = std::regex_replace(string, std::regex("\\$name"), "Somename");
双反斜线。
我很确定'std :: regex_replace'不接受Qt的字符串。 – BartoszKP 2015-07-23 19:06:46
你说得对。正如它发生的那样,QString提供了一种接受QRexExp的替换方法,允许使用Qt自己的东西。但我认为当前的答案可以通过用'string.toStdString()'替换'string'来解决。 – Tom 2015-07-24 22:36:30
或者只是将'String'改为'std :: string',因为这个问题与Qt无关。请考虑这样做 - 我很乐意在之后提供您的答案。 – BartoszKP 2015-07-25 10:07:33
这听起来像一个选项
string.replace(string.find("%s"), string("%s").size(), "Something");
你可以在一个函数包装这个但这一行的解决方案听起来可以接受的。 问题是,这只会改变第一次发生,您可能想循环使用它,但它也允许您使用相同的标记将多个变量插入到此字符串中(%s
)
喜欢的风格,但发现不同的字符串混淆^^'str.replace(str.find(“%s”),string(“%s”)。size(),“Something”);'' – 2017-04-23 14:18:19
我刚刚正在学习C++,但编辑以前发布的一些代码,我可能会使用这样的东西。这使您可以灵活地替换1个或多个实例,还可以指定起点。
using namespace std;
// returns number of replacements made in string
long strReplace(string& str, const string& from, const string& to, size_t start = 0, long count = -1) {
if (from.empty()) return 0;
size_t startpos = str.find(from, start);
long replaceCount = 0;
while (startpos != string::npos){
str.replace(startpos, from.length(), to);
startpos += to.length();
replaceCount++;
if (count > 0 && replaceCount >= count) break;
startpos = str.find(from, startpos);
}
return replaceCount;
}
wstring myString = L"Hello $$ this is an example. By $$.";
wstring search = L"$$";
wstring replace = L"Tom";
for (int i = myString.find(search); i >= 0; i = myString.find(search))
myString.replace(i, search.size(), replace);
如果所有字符串的std :: string,你如果使用sizeof()
,因为它意味着C字符串,而不是C++字符串发现奇怪的问题与字符的截止。修复方法是使用std::string
的.size()
类方法。
sHaystack.replace(sHaystack.find(sNeedle), sNeedle.size(), sReplace);
这取代了sHaystack内联 - 没有必要做一个=分配回来。
用法示例:
std::string sHaystack = "This is %XXX% test.";
std::string sNeedle = "%XXX%";
std::string sReplace = "my special";
sHaystack.replace(sHaystack.find(sNeedle),sNeedle.size(),sReplace);
std::cout << sHaystack << std::endl;
如果你想迅速做到这一点,你可以用两个扫描方法。 伪代码:
我不确定这是否可以优化到就地算法。
和一个C++ 11代码示例,但我只搜索一个字符。的
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
void ReplaceString(string& subject, char search, const string& replace)
{
size_t initSize = subject.size();
int count = 0;
for (auto c : subject) {
if (c == search) ++count;
}
size_t idx = subject.size()-1 + count * replace.size()-1;
subject.resize(idx + 1, '\0');
string reverseReplace{ replace };
reverse(reverseReplace.begin(), reverseReplace.end());
char *end_ptr = &subject[initSize - 1];
while (end_ptr >= &subject[0])
{
if (*end_ptr == search) {
for (auto c : reverseReplace) {
subject[idx - 1] = c;
--idx;
}
}
else {
subject[idx - 1] = *end_ptr;
--idx;
}
--end_ptr;
}
}
int main()
{
string s{ "Mr John Smith" };
ReplaceString(s, ' ', "%20");
cout << s << "\n";
}
可能重复【什么是用C来代替字符串函数?(http://stackoverflow.com/questions/779875/what-is-the-function-to-replace-string-in- c) - 哎呀对不起,这是C,而不是C++;我希望我能解开。 – polygenelubricants 2010-08-05 19:10:27
为什么有一个'C'标签? – sbi 2010-08-05 19:14:03
@poly我认为这一定也被要求提供C++,但我找不到它 – 2010-08-05 19:15:06