Regex 生成 Prompt:用自然语言生成和解释正则表达式
用自然语言描述匹配需求,AI 生成正则表达式并逐段解释含义,同时给出正反例测试串与边界情况提醒。适合写不熟悉的正则,或需要读懂别人写的表达式并确认边界行为是否安全。
发布 2026-06-21更新 2026-10-14用法
描述你要匹配/替换/提取什么内容,AI 生成正则并解释。
什么时候用 / 别用
| 场景 | 用不用 | 原因 |
|---|---|---|
| 日志 / 文本里提取结构化字段 | 用 | 提取型需求本身就是正则的主场 |
| 一次性批量替换(重构改名) | 用 | 但必须先在只读副本上 dry-run |
| 输入格式校验(邮箱 / 手机号 / URL) | 慎用 | 正则只能证明「格式像」,证明不了「真实存在」,关键路径要二次验证 |
| 嵌套 / 递归结构(HTML、JSON、代码) | 别用 | 正则无法可靠处理嵌套,用对应 parser |
能用 startsWith / includes / split 解决 | 别用 | 正则的可维护性是负债,能不用就不用 |
最容易被忽略的一条:正则不适合作安全边界。校验用户输入的合法性可以,但不要用它来「过滤危险内容」——绕过方式太多。
Prompt
你是一个正则表达式专家。请根据我的需求生成正则表达式。
## 需求
{{描述你要匹配什么,比如"匹配中国大陆手机号,1开头11位"}}
## 语言/环境
{{JavaScript / Python / Go / Java / grep / sed}}
## 要求
1. 生成正则表达式
2. 逐段解释每个部分的含义
3. 给出测试用例(匹配 + 不匹配)
4. 如果需求有歧义,列出假设
5. 如果有多种写法,给推荐方案 + 备选方案
## 输出格式
### 正则表达式
```
{{正则}}
```
### 逐段解释
| 部分 | 含义 |
|---|---|
| `^1` | 以 1 开头 |
| `[3-9]` | 第二位 3-9 |
| `\d{9}` | 后面 9 位数字 |
| `$` | 结束 |
### 测试用例
| 输入 | 匹配? | 说明 |
|---|---|---|
| 13800138000 | ✅ | 标准手机号 |
| 12345678901 | ❌ | 第二位是 2,不合法 |
| 1380013800 | ❌ | 只有 10 位 |
### 使用示例
```{{语言}}
// JavaScript
const re = /^1[3-9]\d{9}$/;
console.log(re.test('13800138000')); // true
```
### 注意事项
- {{边界 case}}
- {{性能提醒(如果有回溯风险)}}
常见场景
- 邮箱/手机号/身份证验证
- URL 解析
- 日志提取
- 代码重构(批量替换)
- 数据清洗
一个值得警惕的坑:灾难性回溯
AI 生成的正则能匹配 ≠ 安全。最危险的是灾难性回溯(ReDoS)——某些正则在特定输入下会指数级爆炸,把 CPU 打满。
典型危险写法:嵌套量词 (a+)+、(.*)*、(\d+)*$。比如校验邮箱时写成 ^([a-zA-Z0-9]+)*@,遇到 aaaaaaaaaaaaaaaa!(长串后跟非法字符)会卡死。
所以在 prompt 里追加一句很有用:
"检查这个正则是否有灾难性回溯(ReDoS)风险,特别是嵌套量词。如果有,给一个安全的等价写法。"
另外,能用字符串方法(startsWith/includes/split)解决的,就别上正则——正则的可维护性永远是负债。
为什么有效
- 要求解释而不只是给表达式:正则的可维护性几乎全在「能不能读懂」,一个没人看懂的正则等于一个没人敢改的 bug 源。
- 要求给出灾难性回溯风险:嵌套量词是 ReDoS 的主要来源,不显式问 AI 就不会主动说。
- 要求给测试用例:正则的正确性只能靠正例 + 反例集合证明,自然语言描述天生有歧义。
验收判据:三条过了才算能合
正则的正确性不能靠「看着对」。合并前至少过这三条:
- 正反例集合全绿 —— 正例必须匹配、反例必须不匹配,且反例要包含「长得像但不合法」的样本(如 10 位 / 12 位手机号、第二位是 2 的号段)。
- ReDoS 实测不超时 —— 用递进长度的输入跑超时断言,而不是靠肉眼找嵌套量词:
判据:耗时随长度呈指数增长即判定为灾难性回溯,必须改写。# 输入长度翻倍,耗时若非线性暴涨即为 ReDoS node -e " const re = /<YOUR_RE>/; for (const n of [1000, 2000, 4000, 8000]) { const s = 'a'.repeat(n) + '!'; const t = Date.now(); re.test(s); console.log(n, Date.now() - t + 'ms'); }" - 边界与编码明确 —— 空串、超长串、含换行(
^$是否匹配行首行尾)、Unicode(中文 / emoji 是否按「字符」而非「码元」匹配,JS 需不需要u标志)。
第 2 条是这条 prompt 真正的价值所在。AI 默认会给你一个「能匹配」的正则,但不会主动告诉你它在 8000 字符输入下会卡死——这一句必须显式要求,且必须自己跑一遍。
进阶(自动化)
把生成的正则和用例直接固化成单测,避免下次被「顺手改坏」:
# 用 AI 生成的用例跑一遍,确认正反例都通过
node -e "const re = /<YOUR_RE>/; const ok = ['a@b.com']; const bad = ['a@@b'];
ok.forEach(s => console.assert(re.test(s), 'should match ' + s));
bad.forEach(s => console.assert(!re.test(s), 'should NOT match ' + s));"
三个变体:按你的目的选一个
| 变体 | 追加指令 | 适用 |
|---|---|---|
| A 严格校验 | 「只给唯一推荐写法,并列出所有你明确拒绝的输入类型」 | 表单校验、入库前清洗 |
| B 宽松提取 | 「优先召回率,宁可多匹配也不要漏;输出捕获组命名」 | 日志解析、批量抽取 |
| C 安全改写 | 「先判断是否有 ReDoS 与嵌套量词风险,有则给等价的安全写法并说明差异」 | 任何跑在公网输入上的正则 |
接进管道(headless)
# 把待匹配的样本喂给 AI,让它一次给出正则 + 解释 + 用例
cat samples.txt | claude -p "按 /prompts/regex-generation 的模板,为这些样本生成正则,
采用变体 C(安全改写),并说明每一条不支持的输入类型"
管道里跑出来的正则同样要过上面三条验收判据,headless 只是省了复制粘贴,不省验证。
反例(AI 默认会写的烂版本)
默认输出:^([w.]+)@([w]+.)+[w]{2,}$——嵌套量词 ([w]+.)+ 存在灾难性回溯风险,且没说明它其实不支持带引号的本地部分。
加了 prompt 之后:给出表达式 + 逐段解释 + 明确「长输入下存在回溯风险,建议改用非贪婪或拆成两步校验」+ 6 条正例 4 条反例。
延伸阅读
- SQL 查询生成 Prompt — 同样"自然语言 → 代码"的套路
- 什么是 Prompt Engineering — 让 AI 给测试用例 + 逐段解释的设计思路