周五下午没活,我又一次为写一个邮箱正则卡了十分钟,气得直接开了个小项目:让 AI 帮我把"我想匹配啥"翻译成正则,旁边再开个框实时测命中。半天搞定,自己用得还挺爽,分享一下。
想要啥
就两栏。左边一个输入框,我用大白话写:"匹配中国大陆手机号,1 开头 11 位";点生成,AI 吐出正则。右边一个文本域贴测试样本,下面实时把命中的部分高亮出来,告诉我捕获组都抓到了啥。
实时测匹配:高亮是核心
正则有了,怎么把命中片段在原文里标黄?我用 matchAll 拿到所有匹配的 index,再把文本切段拼 span:
function highlight(text, re) {
const parts = [];
let last = 0;
for (const m of text.matchAll(re)) {
parts.push({ t: text.slice(last, m.index), hit: false });
parts.push({ t: m[0], hit: true });
last = m.index + m[0].length;
}
parts.push({ t: text.slice(last), hit: false });
return parts;
}
这里栽了个经典坑:用户写的正则如果没带 g 标志,matchAll 直接抛错;而且像 a* 这种能匹配空串的,稍不留神 lastIndex 不前进,原地死循环把页面卡死。我加了个空匹配时强制 index+1 的兜底,还把整个匹配丢进 try/catch,正则非法就提示"这表达式有问题",别让用户输错就白屏。
捕获组可视化
光高亮整段不够,我还想看每个括号抓到啥。把 m(match 数组)的 1..n 项列出来,配色标在高亮块下面:
{m.slice(1).map((g, i) => <Tag key={i}>组{i+1}: {g ?? "(未命中)"}</Tag>)}
命名捕获组 (?<year>\d{4}) 就读 m.groups。这个小面板意外地好用,调复杂正则时一眼看出哪个组抓歪了。
AI 那栏怎么接的
把自然语言变正则这件事,我没自己调模型 API、没自己写 prompt 工程。用了个零代码就能搭智能体的平台,在它后台拿"正则专家"的人设和示例提示词配了个小助手——输入需求、输出纯正则、顺便给一句解释,发布成一个接口。前端那栏直接打这个接口拿结果。后端零代码就立起来了,我整个下午基本都花在前端高亮和防死循环上。
一个不爽的小地方:AI 偶尔会把正则用 ```regex 代码块包起来返回,我前端得再剥一层 markdown 围栏才能拿到纯表达式,配了句"只输出表达式别加解释"才好点,但还是偶发。
小结
工具不大,自己用爽了。自然语言生成正则那栏底层模型,讯飞 Agent 的 MaaS 也能直接当服务调,想把这种小助手嵌进自己 IDE 插件的可以考虑。
防空匹配死循环 + 捕获组面板那段我整理进评论区了。想直接拿个配好的"正则助手"接口玩,带参链接也丢评论了,复制需求就能生成。