在文本编辑器中,我们做文本替换时,都是用一个新字符串来替换另一个旧字符串。
MFC将字符串封装为CString类,其方法Replace()符合文本编辑器的操作习惯:
int Replace( TCHAR chOld, TCHAR chNew );
int Replace( LPCTSTR lpszOld, LPCTSTR lpszNew );
但C++ STL中的string类的replace()却有点违反一般的操作习惯,对于Old文本不是直接指定,而是用一段距离(用数字或迭代器来指定一段文本空间范围)来表示,且只做一次替换:
// 以下是重载的一些方法
string (1)
string& replace (size_t pos, size_t len, const string& str);
string& replace (iterator i1, iterator i2, const string& str);
substring (2)
string& replace (size_t pos, size_t len, const string& str,
size_t subpos, size_t sublen);
c-string (3)
string& replace (size_t pos, size_t len, const char* s);
string& replace (iterator i1, iterator i2, const char* s);
buffer (4)
string& replace (size_t pos, size_t len, const char* s, size_t n);
string& replace (iterator i1, iterator i2, const char* s, size_t n);
fill (5)
string& replace (size_t pos, size_t len, size_t n, char c);
string& replace (iterator i1, iterator i2, size_t n, char c);
range (6)
template <class InputIterator>
string& replace (iterator i1, iterator i2, InputIterator first, InputIterator last);
变通的做法就是先要使用find()方法,找出其起始位置,再使用size()方法,求出需要替换的字符个数,然后再应用replace(),所以还要做一下如下的封装:
void replaceChars(string& modifyMe,
const string& findMe, const string& newChars) {
// Look in modifyMe for the "find string"
// starting at position 0:
size_t i = modifyMe.find(findMe, 0);
// Did we find the string to replace?
if(i != string::npos)
// Replace the find string with newChars:
modifyMe.replace(i, findMe.size(), newChars);
}
string& replaceAll(string& context, const string& from,
const string& to) {
size_t lookHere = 0;
size_t foundHere;
while((foundHere = context.find(from, lookHere)) != string::npos) {
context.replace(foundHere, from.size(), to);
lookHere = foundHere + to.size();
}
return context;
}
STL <algorithm>倒是实现了通用的replace()算法,但针对的却是单个的字符(因为其是以序列窗口中的元素的操作对象):
string s("aaaXaaaXXaaXXXaXXXXaaa");
replace(s.begin(), s.end(), 'X', 'Y');
所以你会明白,string也是属于序列类容器,其操作的对象是单个的char。这也是需要与其它序列类容器保持一致的风格,包括迭代器及应用其上的算法,所以其重载的replace()方法就有点违反直觉。而CString的Replace()却没有这些方法的考量或限制,比较符合一般的操作习惯。
string类各种重载的replace()方法的实例:
/*用法一:
*用str替换指定字符串从起始位置pos开始长度为len的字符
*string& replace (size_t pos, size_t len, const string& str);
*/
int main()
{
string line = "this@ is@ a test string!";
line = line.replace(line.find("@"), 1, ""); // 从第一个@位置替换第一个@为空
cout << line << endl;
return 0;
}
//运行结果:
//this is@ a test string!
/*用法二:
*用str替换 迭代器起始位置 和 结束位置 的字符
*string& replace (const_iterator i1, const_iterator i2, const string& str);
*/
int main()
{
string line = "this@ is@ a test string!";
line = line.replace(line.begin(), line.begin()+6, "");
//用str替换从begin位置开始的6个字符
cout << line << endl;
return 0;
}
//运行结果:
//is@ a test string!
/*用法三:
*用substr的指定子串(给定起始位置和长度)替换从指定位置上的字符串
*string& replace (size_t pos, size_t len, const string& str, size_t subpos, size_t sublen);
*/
int main()
{
string line = "this@ is@ a test string!";
string substr = "12345";
line = line.replace(0, 5, substr, substr.find("1"), 3);
//用substr的指定子串(从1位置数共3个字符)替换从0到5位置上的line
cout << line << endl;
return 0;
}
//运行结果:
//123 is@ a test string!
/*用法四:string转char*时编译器可能会报出警告,不建议这样做
*用str替换从指定位置0开始长度为5的字符串
*string& replace(size_t pos, size_t len, const char* s);
*/
int main()
{
string line = "this@ is@ a test string!";
char* str = "12345";
line = line.replace(0, 5, str); //用str替换从指定位置0开始长度为5的字符串
cout << line << endl;
return 0;
}
//运行结果:
//12345 is@ a test string!
/*用法五:string转char*时编译器可能会报出警告,不建议这样做
*用str替换从指定迭代器位置的字符串
*string& replace (const_iterator i1, const_iterator i2, const char* s);
*/
int main()
{
string line = "this@ is@ a test string!";
char* str = "12345";
line = line.replace(line.begin(), line.begin()+9, str);
//用str替换从指定迭代器位置的字符串
cout << line << endl;
return 0;
}
//运行结果:
//12345 a test string!
/*用法六:string转char*时编译器可能会报出警告,不建议这样做
*用s的前n个字符替换从开始位置pos长度为len的字符串
*string& replace(size_t pos, size_t len, const char* s, size_t n);
*/
int main()
{
string line = "this@ is@ a test string!";
char* str = "12345";
line = line.replace(0, 9, str, 4); //用str的前4个字符替换从0位置开始长度为9的字符串
cout << line << endl;
return 0;
}
//运行结果:
//1234 a test string!
/*用法七:string转char*时编译器可能会报出警告,不建议这样做
*用s的前n个字符替换指定迭代器位置(从i1到i2)的字符串
*string& replace (const_iterator i1, const_iterator i2, const char* s, size_t n);
*/
int main()
{
string line = "this@ is@ a test string!";
char* str = "12345";
line = line.replace(line.begin(), line.begin()+9, str, 4);
//用str的前4个字符替换指定迭代器位置的字符串
cout << line << endl;
return 0;
}
//运行结果:
//1234 a test string!
/*用法八:
*用重复n次的c字符替换从指定位置pos长度为len的内容
*string& replace (size_t pos, size_t len, size_t n, char c);
*/
int main()
{
string line = "this@ is@ a test string!";
char c = '1';
line = line.replace(0, 9, 3, c); //用重复3次的c字符替换从指定位置0长度为9的内容
cout << line << endl;
return 0;
}
//运行结果:
//111 a test string!
/*用法九:
*用重复n次的c字符替换从指定迭代器位置(从i1开始到结束)的内容
*string& replace (const_iterator i1, const_iterator i2, size_t n, char c);
*/
int main()
{
string line = "this@ is@ a test string!";
char c = '1';
line = line.replace(line.begin(), line.begin()+9, 3, c);
//用重复3次的c字符替换从指定迭代器位置的内容
cout << line << endl;
return 0;
}
//运行结果:
//111 a test string!
综合实例:
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string var ("abcdefghijklmn");
const string dest ("1234");
string dest2 ("567891234");
var.replace (3,3, dest);
cout << "1: " << var << endl; // 1: abc1234ghijklmn
var = "abcdefghijklmn";
var.replace (3,1, dest.c_str(), 1, 3);
cout << "2: " << var << endl; //2: abc234efghijklmn
var ="abcdefghijklmn";
var.replace (3, 1, 5, 'x');
cout << "3: " << var << endl; // 3: abcxxxxxefghijklmn
string::iterator itA, itB;
string::iterator itC, itD;
itA = var.begin();
itB = var.end();
var = "abcdefghijklmn";
var.replace (itA, itB, dest);
cout << "4: " << var << endl; //4: 1234
itA = var.begin ();
itB = var.end();
itC = dest2.begin () +1;
itD = dest2.end ();
var = "abodefghijklmn";
var.replace (itA, itB, itC, itD);
cout << "5: " << var << endl; //5: 67891234efghijklmn
var = "abcdefghijklmn";
var.replace (3, 1, dest.c_str(), 4); //这种方式会限定字符串替换的最大长度
cout <<"6: " << var << endl;
return 0;
}
/*
程序执行结果为:
1: abc1234ghijklmn
2: abc234efghijklmn
3: abcxxxxxefghijklmn
4: 1234
5: 67891234efghijklmn
6: abc1234efghijklmn
*/
ref
http://www.cplusplus.com/reference/algorithm/replace/?kw=replace
-End-