代码编辑器搜索替换功能实现详解
1. 功能概述
搜索替换是编辑器的核心功能,包括:
- 查找:当前文件、全项目、多文件
- 替换:单处、全部、选中区域
- 搜索选项:大小写敏感、正则表达式、全词匹配
- 过滤:按文件类型、路径筛选
2. 搜索算法
对于普通文本搜索,有多种算法可选:
朴素搜索 O(n*m)
/* 简单但低效,逐字符比较 */
int naive_search(const char *text, const char *pat) {
size_t n = strlen(text), m = strlen(pat);
for (size_t i = 0; i <= n - m; i++) {
if (memcmp(&text[i], pat, m) == 0)
return i; /* 找到返回位置 */
}
return -1;
}
Boyer-Moore 算法
利用坏字符规则和好后缀规则,跳过不可能匹配的区域,适合长模式串。
/* 预处理坏字符表 */
void preprocess_bad_char(const char *pat, int bad[256]) {
int m = strlen(pat);
for (int i = 0; i < 256; i++) bad[i] = m;
for (int i = 0; i < m - 1; i++)
bad[(unsigned char)pat[i]] = m - 1 - i;
}
int boyer_moore(const char *text, const char *pat) {
int bad[256];
preprocess_bad_char(pat, bad);
int n = strlen(text), m = strlen(pat);
int s = 0;
while (s <= n - m) {
int j = m - 1;
while (j >= 0 && pat[j] == text[s + j]) j--;
if (j < 0) return s;
s += max(1, j - bad[(unsigned char)text[s + j]]);
}
return -1;
}
3. 替换逻辑
/* 替换所有匹配项 */
char *replace_all(const char *text, const char *find, const char *replace) {
/* 1. 统计匹配数量和总增长长度 */
int count = 0;
size_t find_len = strlen(find);
size_t replace_len = strlen(replace);
size_t pos = 0;
const char *p = text;
while ((p = strstr(p, find)) != NULL) {
count++;
p += find_len;
}
/* 2. 分配新缓冲区 */
size_t new_len = strlen(text) + count * (replace_len - find_len) + 1;
char *result = malloc(new_len);
char *dst = result;
const char *src = text;
/* 3. 逐个替换 */
while ((p = strstr(src, find)) != NULL) {
memcpy(dst, src, p - src);
dst += p - src;
memcpy(dst, replace, replace_len);
dst += replace_len;
src = p + find_len;
}
strcpy(dst, src);
return result;
}
4. 正则表达式支持
使用 PCRE 库或自己实现简化版正则引擎。
/* 使用 POSIX 正则 */
#include
int regex_search(const char *text, const char *pattern, int *matches, int max) {
regex_t re;
int ret = regcomp(&re, pattern, REG_EXTENDED);
if (ret) return -1;
regmatch_t m[1];
int count = 0;
const char *p = text;
while (count < max && !regexec(&re, p, 1, m, 0)) {
matches[count++] = p - text + m[0].rm_so;
p += m[0].rm_eo;
}
regfree(&re);
return count;
}
5. 性能优化
- 增量搜索:只搜索可见区域,结果随滚动动态更新
- worker 线程:搜索在后台线程执行,避免阻塞 UI
- 结果缓存:相同搜索词直接返回缓存结果
- 延迟搜索:用户停止输入 150ms 后才开始搜索
实战技巧:搜索框使用 debounce 延迟触发;大文件搜索使用 Web Worker;提供搜索进度指示;支持 Ctrl+Enter 在结果中跳转。