--------------------------------------------------------------------------------
标题: String 替换函数源码
作者: 叶飞虎
日期: 2010.03.15
--------------------------------------------------------------------------------
1 /* 头文件(.h) */
2
3 // 在 AStr 中查找 AOld 串, 并使用 ANew 替换
4 // 注: SameStr(AOld, ANew, true) 必须为 false, 内部不检查是否相同
5 // 如: StringReplace("aabbccddbbcc", "bc", "x", true) 返回值为: "aabxcddbxc"
6 KYString StringReplace(const char* AStr, long ALength,
7 const char* AOld, long AOldLen,
8 const char* ANew, long ANewLen,
9 bool AReplaceAll = false,
10 bool ACaseSensitive = true);
11 KYString StringReplace(const KYString& AStr, const char* AOld, long AOldLen,
12 const char* ANew, long ANewLen,
13 bool AReplaceAll = false,
14 bool ACaseSensitive = true);
15 inline KYString StringReplace(const KYString& AStr, const KYString& AOld,
16 const KYString& ANew, bool AReplaceAll = false,
17 bool ACaseSensitive = true)
18 {
19 return StringReplace(AStr, (char*)AOld, AOld.Length(),
20 (char*)ANew, ANew.Length(),
21 AReplaceAll, ACaseSensitive);
22 }
23
24 // 给字符串加单引号, 若字符中存在单引号则自动添加二个单引号
25 // 如: QuotedStr("abc'123'def") 返回值为: "'abc''123''def'"
26 KYString QuotedStr(const char* AStr, int ALength);
27 inline KYString QuotedStr(const KYString& AStr)
28 {
29 return QuotedStr((char*)AStr, AStr.Length());
30 }
31
32
33 /* 源文件(.cpp) */
34
35 // 在 AStr 中查找 AOld 串, 并使用 ANew 替换
36 // 如: StringReplace("aabbccddbbcc", "bc", "x", true) 返回值为: "aabxcddbxc"
37 // 注: 1. 若未找到 AOld 串则返回空串并 ANoFound == true, 否则 ANoFound == false;
38 // 2. 参数 AStr, ALength, AOld, ALen 必须合法
39 // 3. SameStr(AOld, ANew, true) 必须为 false, 内部不检查是否相同
40 static KYString _DoStringReplace(const char* AStr, long ALength,
41 const char* AOld, long AOldLen,
42 const char* ANew, long ANewLen,
43 bool AReplaceAll, bool ACaseSensitive,
44 bool& ANoFound)
45 {
46 // 初始化
47 KYString result, strNext;
48 int* pNext;
49 long intPos;
50
51 // 校正长度
52 if ((ANew == NULL) || (ANewLen < 0))
53 ANewLen = 0;
54
55 // 分配缓冲区
56 strNext.SetLength(sizeof(int) * AOldLen);
57 pNext = (int*)(char*)strNext;
58
59 // 得到目标串的 KMP 的回溯表
60 GetKMPNext(AOld, AOldLen, pNext, ACaseSensitive);
61
62 // 查找第一个匹配
63 ANoFound = false;
64 intPos = _FindNext(AStr, ALength, AOld, AOldLen,
65 pNext, 1, 1, ACaseSensitive) - 1;
66 if (intPos < 0)
67 ANoFound = true;
68 else if (!AReplaceAll)
69 {
70 // 分配空间
71 result.SetLength(ALength + (ANewLen - AOldLen));
72 char* pPos = (char*)result;
73
74 // 拷贝数据
75 if (pPos != NULL)
76 {
77 // 拷贝前半部
78 if (intPos > 0)
79 {
80 memcpy(pPos, AStr, intPos);
81 pPos += intPos;
82 }
83
84 // 拷贝新串
85 if (ANewLen > 0)
86 {
87 memcpy(pPos, ANew, ANewLen);
88 pPos += ANewLen;
89 }
90
91 // 拷贝后半部
92 intPos += AOldLen;
93 ALength -= intPos;
94 if (ALength > 0)
95 {
96 AStr += intPos;
97 memcpy(pPos, AStr, ALength);
98 }
99 }
100 }
101 else
102 {
103 // 初始化
104 KYString strNew;
105 char* pBegin;
106 char* pPos;
107 long intLen;
108
109 // 计算最大尺寸
110 if (ANewLen <= AOldLen)
111 intLen = ALength + (ANewLen - AOldLen);
112 else if (AOldLen == 1)
113 intLen = intPos + ANewLen * (ALength - intPos);
114 else
115 intLen = ALength + (ANewLen - AOldLen) * ((ALength - intPos) / AOldLen);
116
117 // 分配缓冲区
118 strNew.SetLength(intLen);
119 pBegin = (char*)strNew;
120 pPos = pBegin;
121
122 // 拷贝数据
123 if (pPos != NULL)
124 {
125 // 循环查找
126 do
127 {
128 // 拷贝前半部
129 if (intPos > 0)
130 {
131 memcpy(pPos, AStr, intPos);
132 pPos += intPos;
133 }
134
135 // 拷贝新串
136 if (ANewLen > 0)
137 {
138 memcpy(pPos, ANew, ANewLen);
139 pPos += ANewLen;
140 }
141
142 // 查找下一匹配项
143 intPos += AOldLen;
144 AStr += intPos;
145 ALength -= intPos;
146 intPos = _FindNext(AStr, ALength, AOld, AOldLen,
147 pNext, 1, 1, ACaseSensitive) - 1;
148 } while (intPos >= 0);
149
150 // 拷贝后半部
151 if (ALength > 0)
152 {
153 memcpy(pPos, AStr, ALength);
154 pPos += ALength;
155 }
156
157 // 设置结果
158 result.SetString(pBegin, pPos - pBegin);
159 }
160 }
161
162 // 返回结果
163 return result;
164 }
165
166 // 在 AStr 中查找 AOld 串, 并使用 ANew 替换
167 // 注: SameStr(AOld, ANew, true) 必须为 false, 内部不检查是否相同
168 // 如: StringReplace("aabbccddbbcc", "bc", "x", true) 返回值为: "aabxcddbxc"
169 KYString StringReplace(const char* AStr, long ALength,
170 const char* AOld, long AOldLen,
171 const char* ANew, long ANewLen,
172 bool AReplaceAll, bool ACaseSensitive)
173 {
174 // 初始化
175 KYString result;
176 bool boolNoFound = true;
177
178 // 检查参数
179 if ((AStr != NULL) && (AOld != NULL) && (AOldLen > 0) && (ALength >= AOldLen))
180 result = _DoStringReplace(AStr, ALength, AOld, AOldLen, ANew, ANewLen,
181 AReplaceAll, ACaseSensitive, boolNoFound);
182
183 // 若未找到则拷贝数据
184 if (boolNoFound)
185 result.SetString(AStr, ALength);
186
187 // 返回结果
188 return result;
189 }
190
191 // 在 AStr 中查找 AOld 串, 并使用 ANew 替换
192 // 注: SameStr(AOld, ANew, true) 必须为 false, 内部不检查是否相同
193 // 如: StringReplace("aabbccddbbcc", "bc", "x", true) 返回值为: "aabxcddbxc"
194 KYString StringReplace(const KYString& AStr, const char* AOld, long AOldLen,
195 const char* ANew, long ANewLen,
196 bool AReplaceAll,
197 bool ACaseSensitive)
198 {
199 // 初始化
200 KYString result;
201 bool boolNoFound = true;
202
203 // 检查参数
204 if ((AOld != NULL) && (AOldLen > 0) && (AStr.Length() >= AOldLen))
205 result = _DoStringReplace((char*)AStr, AStr.Length(),
206 AOld, AOldLen, ANew, ANewLen,
207 AReplaceAll, ACaseSensitive, boolNoFound);
208
209 // 若未找到则拷贝数据
210 if (boolNoFound)
211 result = AStr;
212
213 // 返回结果
214 return result;
215 }
216
217 // 给字符串加单引号, 若字符中存在单引号则自动添加二个单引号
218 // 如: QuotedStr("abc'123'def") 返回值为: "'abc''123''def'"
219 KYString QuotedStr(const char* AStr, int ALength)
220 {
221 // 字符
222 #define Char_Quoted '\'' // 单引号
223
224 // 静态常量
225 static const KYString Str_Null = "''";
226
227 // 初始化
228 KYString result;
229
230 // 判断是否为空串
231 if ((AStr == NULL) || (ALength <= 0))
232 result = Str_Null;
233 else
234 {
235 // 分配足够的字符串空间
236 KYString strNew;
237 strNew.SetLength(ALength + ALength + 2);
238
239 // 初始化
240 char* pBegin = (char*)strNew;
241 char* pPos = pBegin;
242 char* pStr = (char*)AStr;
243 char* pEnd = pStr + ALength;
244
245 // 左引号
246 *(pPos++) = Char_Quoted;
247
248 // 循环操作
249 while (pStr < pEnd)
250 {
251 // 判断是否单引号
252 if (*pStr == Char_Quoted)
253 *(pPos++) = Char_Quoted;
254
255 // 字符赋值, 下一字符
256 *(pPos++) = *(pStr++);
257 }
258
259 // 右引号
260 *(pPos++) = Char_Quoted;
261
262 // 设置返回值
263 result.SetString(pBegin, pPos - pBegin);
264 }
265
266 // 返回结果
267 return result;
268 }
269
posted on 2011-05-22 12:05
Kyee Ye 阅读(634)
评论(0) 编辑 收藏 引用 所属分类:
C++类库KYLib 、
源码