如何用 AI 编写正则表达式并测试:引擎、转义与 ReDoS 检查

如何用 AI 编写正则表达式并测试:引擎、转义与 ReDoS 检查

Olivia Park
2026年9月4日· 8 分钟阅读

要用 AI 编写正则表达式,先指定引擎与契约,再运行真实测试。遵循如何使用 AI限定范围;是否有效由目标引擎决定。

关键要点

  • 写清运行时、引擎、版本、API、标志及完整匹配或搜索语义。
  • 先把需求转成允许列表式契约,再写语法。
  • 测试接受、拒绝、边界、Unicode、换行与对抗输入。
  • 分开处理正则、编程语言字符串和命令行外壳转义。
  • 不只检查 true/false,还要验证捕获组与替换结果。
  • 用受限输入测试性能,检查灾难性回溯。
  • 表达式难以解释时改用解析器或普通字符串操作。

用 AI 编写正则表达式前先定义匹配契约

正则无法修复含糊需求。先说明允许与禁止内容、是否匹配完整值,以及后续代码会怎样使用捕获结果。

以一个合成工单号为例,契约可以是:

字段决定
合法形状两个 ASCII 大写字母、连字符、四位数字
是否完整匹配是,不允许前后文字
长度恰好 7 个字符
合法例子AB-0042、ZX-9000
非法例子ab-0042、AB 0042、AB-42、XAB-0042Y
捕获前缀和数字部分
输入来源不可信表单字段
匹配前长度上限64 个字符

OWASP 建议在输入校验中定义允许字符集合及最小、最大长度。[4]领域允许时优先使用狭窄的允许列表。不要要求“适用于任何标识符的完美正则”,而要写明真实语法和政策负责人。

校验与提取也要分开。能在段落中找到工单号的表达式,不应自动用于验证整个表单值;客户端便利校验也不能替代服务端执行。

表达式实际由哪个引擎、在哪个调用点执行?

JavaScript、Python、Java、.NET、Rust crate、数据库函数、命令行工具和编辑器的正则并不完全相同。即使语法相同,API 与默认值也可能不同。

记录:

字段示例
语言/运行时Python 3.14
引擎/库标准 re 模块
APIre.fullmatch
表达式表示原始字符串字面量
标志无
Unicode 政策契约只允许 ASCII 字母
捕获命名组 prefix 与 number
替换行为不使用

MDN 说明 JavaScript 标志会改变全局搜索、忽略大小写、多行锚点、点号匹配换行及 Unicode 等行为。[1]Python re 则有自己的语法、标志、匹配函数与替换反向引用。[2]在线测试器通过不是充分证据,除非它与目标引擎和配置完全一致。

完整匹配、前缀匹配和搜索是三个不同契约。JavaScript 常用 ^、$ 表达整值校验,而 Python 可以用 fullmatch 在 API 层表达。仍须测试换行与多行模式行为,不能假定所有锚点语义相同。

在编写表达式之前建立正则表达式测试用例

测试案例应让不懂正则语法的负责人也能审批。先用需求给出的例子,再补边界与近似失败。

用例输入期望理由
P-01AB-0042匹配;AB、0042常规合法值
P-02ZX-9000匹配;ZX、9000不同合法值
N-01ab-0042不匹配禁止小写
N-02AB 0042不匹配分隔符错误
N-03AB-42不匹配数字不足
N-04XAB-0042Y不匹配前后多出文字
B-01空字符串不匹配最小边界
B-0264 字符失败值预算内失败最大输入边界
A-01长重复前缀加 !预算内失败回溯挑战

不要让 AI 同时决定规则与所有期望结果。预言必须来自产品需求、协议、标准或政策。生成测试的方法能扩展矩阵,但标签由负责人批准。

继续加入空值、长度边界上下各一、重复分隔符、嵌入换行、易混 Unicode、首尾空白、调用点的 null 处理和超长拒绝值。若捕获内容会进入后续操作,就精确写出每个捕获值。

要求 AI 同时给出表达式与解释

提供契约和合成测试表,不提供私人生产样本。

目标:Python 3.14 标准 re,使用 re.fullmatch 与 raw string。
契约:恰好两个 ASCII 大写字母、一个字面连字符、四位数字。
返回一个包含 `prefix` 与 `number` 命名组的表达式。
逐个符号解释并列出假设,不得扩大允许字符。
不得创造额外需求;为每个给定案例提供可执行测试。
引擎或转义不确定项标为 [VERIFY]。

候选可以是:

pattern = r"(?P<prefix>[A-Z]{2})-(?P<number>[0-9]{4})"

由于调用点使用 re.fullmatch,此合成例子无需显式锚点。这是特定引擎和 API 的结论,不是普遍风格要求。要求解释每个组、量词、字符类、分支、前后向断言与标志;删除没有契约用途的语法。

哪三层转义必须分开处理?

很多错误来自正确的正则被错误字符串包裹。分别记录:

  1. 正则语法: 数字类、字面点、组或反向引用;
  2. 语言字符串: 源代码怎样表示反斜线与引号;
  3. 传输或命令行外壳: JSON、YAML、命令行或模板怎样再次编码。

Python 原始字符串通常更易读,但仍遵守 Python 自己的原始字符串规则。JavaScript 正则字面量和 new RegExp("...") 的字符串转义需求不同。替换字符串可能又使用另一套语法;Python 文档记录了 \g<name> 与 \g<number> 等命名及编号引用。[2]

保存源代码字面量、可查看的运行时表达式值,以及实际执行调用。需要时测试字面反斜线、引号、换行和替换捕获。不要靠试错“修好”转义而不说明改变了哪一层。

如何在目标运行时测试 AI 生成的正则?

把整个语料放进真实项目测试框架。一个合成 Python 例子如下:

import re

PATTERN = re.compile(r"(?P<prefix>[A-Z]{2})-(?P<number>[0-9]{4})")

def parse_ticket(value: str):
    if len(value) > 64:
        return None
    return PATTERN.fullmatch(value)

assert parse_ticket("AB-0042").groupdict() == {
    "prefix": "AB",
    "number": "0042",
}
assert parse_ticket("ab-0042") is None
assert parse_ticket("XAB-0042Y") is None

长度检查在匹配前限制工作量,64 只来自合成契约。真实应用还应先检查类型和空值。即使浏览器已校验,也要运行服务端测试。

若正则执行替换,要断言完整输出及未匹配部分;若使用全局或有状态 API,要检查重复调用和空匹配;若处理多行,覆盖两种常见换行及所选多行模式语义。

检查 Unicode、标志、捕获和替换

字符类暗含政策决定。目标引擎中的 \d 是 ASCII 数字还是更广的 Unicode 类别?忽略大小写会否折叠 A-Z 之外字符?点号会否匹配换行?全局标志会否在调用间保留状态?

建立一张复核表:

维度问题证据
Unicode哪些文字与规范化形式合法?获批语料
空白空格、制表符、换行是否不同?边界测试
标志每个标志为何存在?运行时配置
捕获名称和可选值是否稳定?精确断言
替换缺失组怎样处理?输出夹具
迭代空匹配会否卡住循环?循环测试

不要用仅限 ASCII 的表达式验证国际姓名,也不要让协议标识意外接受所有 Unicode 数字。政策由产品或协议负责人决定,模型只实现记录下来的规则。

怎样测试正则 ReDoS 风险与性能?

部分回溯引擎在特制输入上会急剧变慢。OWASP 指出,重复组内再出现重复或重叠分支是典型风险,并列出 (a+)+$ 等例子。[3]因此语料必须包含长失败输入。

检查嵌套歧义量词、重叠分支、作用于不受控文字的反向引用,以及由用户输入构造的表达式。然后:

  1. 在匹配前限制输入长度;
  2. 适当使用更安全的等价写法或非回溯引擎;
  3. 在受控进程基准测试普通与对抗失败;
  4. 运行时支持安全机制时,在正则外设置超时或资源边界;
  5. 记录引擎、硬件类别、输入生成方式、次数与阈值。

不要发布通用“10 毫秒内安全”结论。预算属于具体应用与环境,模型声称线性也不是测量或证明。

不要把原始用户输入拼进正则。字面搜索应使用引擎的转义函数,并继续限制输入。若确实允许用户提供表达式,应作为独立高风险功能,采用引擎隔离、资源限制与安全审查。

何时不该使用正则

语法嵌套、依赖上下文或由标准长期维护时,改用普通字符串操作、解析器或领域库。HTML、编程语言、复杂地址和持续变化的业务规则通常不应由一个难以阅读的表达式独自承担。

出现以下情况就停止:

  • 复核人无法逐个符号解释;
  • 变体需要重叠嵌套分支;
  • 引擎缺少所需 Unicode 或超时行为;
  • 捕获组形成不稳定隐藏 API;
  • 语法之后仍需规范化或语义校验;
  • 已有维护良好的标准解析器;
  • 测试语料无法清楚描述接受与拒绝边界。

具体失败可按AI 调试流程缩小差异;周边生成代码则采用运行前审查清单。

总结检查表

  • 用 AI 编写正则表达式所用的语言、引擎、版本、API、标志与表示方式已记录。
  • 契约写明字符集、长度、完整匹配、捕获与用途。
  • 已有正例、反例、边界、Unicode、换行及对抗案例。
  • 期望结果来自负责人或标准,不由模型独自决定。
  • 正则、字符串、JSON/YAML 与命令行外壳转义没有混淆。
  • 候选在目标环境编译并运行全部案例。
  • 捕获、替换、重复执行和空匹配均被检查。
  • 输入长度受限,ReDoS 风险完成复核。
  • 另一位维护者能解释表达式。
  • 正则不合适时改用解析器。

常见问题

只给一个例子,能用 AI 编写正则表达式吗?

一个例子无法定义全部接受与拒绝输入。提供书面契约、正反例、边界和对抗案例,再在目标引擎执行。

为什么用 AI 编写正则表达式后,在线测试通过但代码失败?

测试器可能使用不同引擎、标志、匹配 API 或转义层。必须在项目中重现实际运行时表达式与调用点。

应使用锚点还是完整匹配 API?

选择能在目标引擎中准确表达完整值匹配的写法。锚点行为可能因引擎而异,因此务必测试嵌入换行和多行模式标志。

用 AI 编写正则表达式时,正则转义与字符串转义有什么区别?

正则转义定义表达式语法,字符串转义定义源代码怎样保存它;JSON、YAML、模板和命令行外壳还可能增加更多层。

\d 总是等于 [0-9] 吗?

不是。某些引擎或模式会让 \d 匹配更广的 Unicode 数字。应根据输入政策选择字符类并加入代表性测试。

用 AI 编写正则表达式时,怎样测试 ReDoS 风险?

复核结构、限制输入、加入长对抗失败值,并在真实引擎与受控资源下测量。不能只相信模型的复杂度判断。

可以把用户输入放入正则吗?

不要把它直接拼成表达式。字面搜索使用转义函数;只有明确需要用户自定义表达式时,才设计隔离和资源上限。

什么时候应放弃用 AI 编写正则表达式,改用解析器?

数据具有嵌套、上下文依赖、标准语法,或小型表达式已无法清楚解释时,应使用解析器。可维护性也是正确性的一部分。

来源

  1. MDN Web Docs, “Regular expressions” — https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions
  2. Python documentation, “re — Regular expression operations” — https://docs.python.org/3/library/re.html
  3. OWASP Foundation, “Regular expression Denial of Service — ReDoS” — https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
  4. OWASP Cheat Sheet Series, “Input Validation” — https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html

Sources checked 2026 年 9 月 4 日。

延伸阅读

开启 3 天免费试用

注册即可免费体验全部高级功能。

*仅限新用户;每位用户只能获得一次试用。

如何用 AI 编写正则表达式并测试:引擎、转义与 ReDoS 检查 | AethoVPN