SKILL.md
5.7 KB查看源码正则表达式构建与排错助手#
把一句模糊的匹配需求变成一个能跑、能解释、有测试用例兜底的正则表达式。也能反过来:拿到一段看不懂的正则,逐段拆解成人话。纯指令技能,不带任何脚本,不联网,不写文件;所有工作都在对话中完成。
触发时机#
满足以下任一条件即进入本技能:
- 用户描述一段"想匹配什么"的文字,要求写出对应的正则;
- 用户给出一个正则,说它"匹配不上"、"匹配多了"或"报错",要求修复;
- 用户贴出一段别人的正则,要求解释每一段在干什么;
- 用户要求把正则从一种语言/工具迁移到另一种(如 Python 到 JavaScript、grep 到 sed)。
工作流程#
第一步:需求确认(新建正则时必做)#
逐项向用户确认,缺一项就先问,不要凭空猜:
- 目标文本样本:至少 2 条应匹配的示例 + 2 条不应匹配的示例。没有反例的正则一律不交付。
- 匹配范围:是提取、校验、替换还是切分?校验要求全文匹配,提取只关心子串,两者写法完全不同。
- 运行方言:正则在哪种环境里跑?PCRE(PHP/Grep -P)、Python
re、JavaScript、Java、.NET、Go(RE2,不支持回溯)、还是 sed/awk?方言间捕获组语法、lookaround 支持、Unicode 处理差异巨大。 - 大小写与多行:是否需要忽略大小写(
i标志)、跨行匹配(m/s标志)、处理 Windows 换行(\r?\n)?
第二步:分步构建#
不要一步写出完整正则,按顺序搭积木,每步说明这一段负责什么:
- 拆解需求为原子片段(字面量、字符类、数量词、分组、位置锚点);
- 先写"骨架"——能匹配正例的最宽松版本,确认能跑通;
- 逐个片段收紧:加锚点、收紧字符类、加边界(
\b、(?<!))排除反例; - 给每个分组起名字(
(?P<name>...)或(?<name>...),按方言),提升可读性; - 标注哪些位置用了回溯,评估是否存在灾难性回溯风险(见红线)。
第三步:用例验证#
交付前必须在脑中(或让用户运行)过一遍用例对照表:
| 输入样本 | 期望结果 | 实际推断 | 是否通过 |
|---|---|---|---|
| (正例 1) | 匹配,捕获到… | … | ✅ |
| (反例 1) | 不匹配 | … | ✅ |
| (边界样本) | … | … | ✅ |
边界样本至少覆盖:空字符串、单个字符、恰好达到/超过长度上限、特殊字符(引号、反斜杠、换行)、多字节中文。
修复排错清单(用户拿来的正则不工作时逐项排查)#
按命中率从高到低依次检查:
- 锚点缺失:想全文校验却没加
^...$(或\A...\z),导致子串误匹配; - 贪婪误伤:
.*/.+吃掉过多内容——考虑改懒惰(*?)或排除型字符类([^"]*); - 转义遗漏:
. + * ? ( ) [ ] { } | ^ $ \在字符类外是元字符,未转义会改变语义;字符类内] ^ - \需要注意位置; - 方言不兼容:lookaround、命名分组、
\d的 Unicode 语义在不同引擎不同;Go/RE2 完全不支持回溯和 lookaround; - 换行陷阱:
.默认不匹配换行;跨行文本要加s标志或用[\s\S]; - 量词叠罗汉:
(a+)+、(\w*)*这类嵌套量词是灾难性回溯的典型来源; - 空白假设:源文本里的全角空格、不可见字符、BOM 是否被
\s或字面空格覆盖。
输出模板#
最终交付固定用以下结构:
【正则】
<正则原文,一行>
【方言与标志】
适用引擎:<…>;标志:<i/m/s/… 或"无">
【逐段解释】
<片段 1> —— 作用…
<片段 2> —— 作用…
【用例对照表】
(按第三步表格给出,正例反例都要有)
【注意事项】
- 性能:是否存在回溯风险及规避方法
- 迁移:换引擎时需要改哪几处
红线条款#
以下情形必须停下来说明,不得交付:
- 禁止交付没有反例验证的正则——用户没给反例时先要,而不是直接输出;
- 禁止用正则解析 HTML/XML/JSON 等嵌套结构——明确告知应使用对应解析器,正则只做简单词法层面任务;
- 禁止在正则中内嵌敏感数据(如把具体密码、密钥片段写进字符类或字面量);
- 禁止交付存在灾难性回溯风险且未标注的正则——嵌套量词、相邻模糊量词必须改写或明确警告;
- 禁止声称正则"百分百精确"——文本校验的正则永远要提示服务端/程序侧二次校验(如邮箱、URL、手机号);
- 修复别人正则时禁止只给结果不给原因——必须指出原表达式哪一段出了什么问题。
常用配方(可作起点,交付前仍须走完整流程)#
- 浮点数(含负号):
^-?\d+(\.\d+)?$ - 中文与英文混排长度校验:先按
\u4e00-\u9fa5占 2 位换算再计数,不建议纯正则解决; - 逗号分隔列表:
^\S+(,\S+)*$(禁止首尾逗号与空项); - 提取键值对:
(?m)^(?<key>[^=:]+)\s*[=:]\s*(?<value>.+)$; - 版本号:
^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$(SemVer 简化版)。
配方只是起点:任何配方在交付前都必须经过第三步的用例对照表验证,并按用户的方言调整。
文件内容是平台检查时读出的文本,只供查看。平台不会运行包里的任何脚本或程序。

