C语言高亮嵌套匹配文本问题:现有代码无法处理重叠匹配
解决C语言文本高亮中的重叠匹配问题
需求是将输出文本中所有匹配的内容标红,需正确处理嵌套/重叠匹配。例如输入文本为aaaX,搜索文本为aa时,预期输出是红色背景的aaa加正常的X,但现有代码仅能匹配前两个a,输出红色背景的aa加正常的aX。
现有代码问题分析
现有代码在匹配到一段文本后,直接通过i += j - 1跳过了已匹配的字符,导致后续重叠的匹配位置无法被检测到。比如匹配aaaX的前两个a后,i跳到1,下一次循环从i=2开始,第三个a不会被检查是否能和前一个a组成新的aa匹配,因此无法将第三个a纳入高亮范围。
解决方案:先标记后输出
正确的思路是先遍历整个字符串,标记所有需要高亮的字符位置,再根据标记统一输出文本,这样可以自然合并重叠或连续的高亮区域。
实现代码
#include <stdio.h> #include <string.h> #include <stdbool.h> #include <stdlib.h> const char *RED_TEXT = "\x1b[41;1m"; const char *RESET_TEXT = "\x1b[0m"; void highlightText(const char *line, const char *searchText) { int lineLen = strlen(line); int searchLen = strlen(searchText); // 处理空输入的边界情况 if (searchLen == 0 || lineLen == 0) { printf("%s", line); return; } // 分配标记数组,初始全为false bool *highlight = calloc(lineLen, sizeof(bool)); if (!highlight) { printf("%s", line); return; } // 遍历所有可能的起始位置,标记匹配字符 for (int i = 0; i <= lineLen - searchLen; i++) { int matchCount = 0; while (matchCount < searchLen && line[i + matchCount] == searchText[matchCount]) { matchCount++; } if (matchCount == searchLen) { // 将匹配到的所有字符标记为需要高亮 for (int k = 0; k < searchLen; k++) { highlight[i + k] = true; } } } // 根据标记输出高亮文本 bool inHighlight = false; for (int i = 0; i < lineLen; i++) { if (highlight[i] && !inHighlight) { printf("%s", RED_TEXT); inHighlight = true; } else if (!highlight[i] && inHighlight) { printf("%s", RESET_TEXT); inHighlight = false; } printf("%c", line[i]); } // 确保结束时重置高亮状态 if (inHighlight) { printf("%s", RESET_TEXT); } free(highlight); } // 测试示例 int main() { const char *testLine = "aaaX"; const char *search = "aa"; highlightText(testLine, search); printf("\n"); return 0; }
代码说明
标记阶段:
- 创建一个布尔数组
highlight,长度与输入文本一致,用于记录每个字符是否需要高亮。 - 遍历文本中所有可能的匹配起始位置,若找到完整匹配,则将对应位置的数组元素设为
true。重叠的匹配会多次标记同一位置,但最终结果仍为true,不影响后续输出。
- 创建一个布尔数组
输出阶段:
- 遍历文本,根据
highlight数组的标记切换高亮状态:进入高亮区域时输出红色控制码,退出时输出重置控制码。 - 连续的高亮字符会被包裹在同一组控制码中,实现预期的合并效果。
- 遍历文本,根据
内容的提问来源于stack exchange,提问作者HenrijsS
相关产品推荐
相关产品推荐

