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