正则测试:命中、分组与替换预览,以及零宽匹配的坑
自己写一个正则测试页要处理三件事:把命中位置和分组讲清楚、把替换结果先预览出来、以及别让零宽匹配把页面卡死。
为什么要自己写
在线正则测试站很多,但它们通常要求你把待测文本贴到别人的服务器上,而且很少解释「为什么这里标红了」。我要的是一个本地的、把匹配细节摊开的页面。
命中结果要说清三件事
第一是命中区间:每处匹配的起始与结束偏移。只有知道偏移,才能把高亮画在对的位置。
第二是捕获分组:不仅是整体匹配,还要列出每个分组的内容与序号,未参与匹配的分组标成 undefined 而不是空字符串——这两者在后续处理里完全不一样。
第三是替换预览:给出替换后的完整文本,而不是只把命中处标个色。正则替换最容易出的错是分组引用写错,只有看到结果才知道。
零宽匹配不能卡死
这是实现里唯一的真坑。用带 g 标志的正则做全局匹配时,如果某次匹配长度为 0(^、$ 或纯前瞻断言都属于此类),lastIndex 不会前进,循环就永远不会结束,页面直接卡死。
所以每次匹配后都要主动推进:
const step = match[0].length === 0 ? 1 : 0;
re.lastIndex = match.index + match[0].length + step;
同时要设一个匹配数量上限,避免灾难性回溯把浏览器拖死。正则写错了不该等于页面挂掉。
高亮靠分段,不靠替换字符串
把原文切成「未命中 / 命中 / 未命中……」的片段数组,模板只负责渲染片段。这样不需要往 HTML 里插标记,也就不会因为用户文本里带有标签字符而破坏结构。
内置模板与本地运行
邮箱、URL、IPv4、日期这类模式内置成模板,省去从零写。所有解析都在浏览器里完成,逻辑模块是零依赖、不碰 DOM 的纯函数,因此可以被项目的自检脚本直接跑——它顺便覆盖了上面那些零宽与上限的分支。

评论
…