实际上,您可以在具有 realloc 的语言中就地执行此操作(如果 realloc 就地成功,则根本无法保证)。
如果替换字符串比原始模式长,那么我们首先扫描模式并计算新字符串的长度。然后我们调用 realloc 来扩展可用的缓冲区并开始向后复制到字符串。
[A][B][C][D][B][C][C][D][A][B][C][D][␀]
# extend buffer:
[A][B][C][D][B][C][C][D][A][B][C][D][␀][ ][ ][ ]
# after first few iterations of the copy loop
[A][B][C][D][B][C][C][D][A][B][C][D][␀][ ][ ][␀]
[A][B][C][D][B][C][C][D][A][B][C][D][␀][ ][D][␀]
[A][B][C][D][B][C][C][D][A][B][C][D][␀][C][D][␀]
[A][B][C][D][B][C][C][D][A][B][C][U][V][W][D][␀]
[A][B][C][D][B][C][C][D][A][B][A][U][V][W][D][␀]
我的 C 有点生锈,但这段代码似乎可以完成这项工作:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int pat_match(char* str, char* pattern)
{
while(*pattern == *str)
{
if(*pattern == '\0' || *str == '\0') break;
pattern++;
str++;
}
return (*pattern == '\0');
}
char* replace(char* str, char* pattern, char* rep)
{
int len_str = strlen(str);
int len_pattern = strlen(pattern);
int len_rep = strlen(rep);
if(len_rep > len_pattern)
{
int count_matches = 0;
char* scan = str;
while(*scan)
{
if(pat_match(scan, pattern))
{
printf("Match!\n");
count_matches++;
scan += len_pattern;
}
else
{
scan++;
}
}
if(count_matches == 0) return str;
int len_new = len_str + count_matches * (len_rep - len_pattern);
str = realloc(str, len_new+1);
int new_pos, pos;
for(pos=len_str-1,new_pos=len_new-1;pos>=0;pos--,new_pos--)
{
if(pat_match(str+pos, pattern))
{
memcpy(str+new_pos-(len_rep-len_pattern), rep, len_rep);
new_pos = new_pos - (len_rep-len_pattern);
}
else
{
str[new_pos] = str[pos];
}
}
str[len_new] = '\0';
}
else
{
int new_pos, pos;
for(pos=0,new_pos=0; pos<len_str; pos++,new_pos++)
{
if(pat_match(str+pos, pattern))
{
memcpy(str+new_pos, rep, len_rep);
pos += len_pattern-1;
new_pos += len_rep-1;
}
else
{
str[new_pos] = str[pos];
}
}
str[new_pos] = '\0';
}
return str;
}
void main()
{
char* s = (char*)malloc(12);
strcpy(s, "Hello world");
printf("%s\n", replace(s, "llo", "x"));
}