正则性能测试在线 - 回溯耗时与 ReDoS 风险初筛

用正常、最长合法和近似匹配失败的文本比较正则执行耗时,观察长度增长带来的趋势,帮助初筛嵌套量词、灾难性回溯和 ReDoS 风险;浏览器基准不能替代生产压测。

功能特点

  • 重复运行表达式并记录当前浏览器中的执行耗时
  • 用正常、最长合法和近似失败输入观察耗时随长度变化的趋势
  • 对比候选表达式,辅助发现嵌套量词与歧义分支;生产结论仍需在目标服务压测

使用方法

  1. 输入表达式并准备正常、最长合法和近似失败文本
  2. 从短输入开始按长度递增运行,记录多次耗时趋势而非单次数字
  3. 限制浏览器样本上限,改写高风险结构,再在目标服务用并发、超时和真实负载复测

示例输入

  • 高风险回溯

    ^(a+)+$ against aaaaaaaaaaaaaaaaa!

    适合观察灾难性回溯风险和输入长度变化带来的耗时。

  • 日志提取性能

    ERROR 2026-07-19 request_id=abc latency=120ms

    适合比较多个表达式在相同样本上的执行表现。

  • 长度增长与近似失败

    表达式:^(a+)+$
    样本:a×16!、a×32!、a×64!

    同时观察正常、最长合法和最终失败的输入;只保留短步长与安全上限,避免冻结浏览器。

  • 生产压测边界

    服务端方法:POST /validate
    指标:p50/p95/p99、超时、CPU、并发和最大输入长度

    浏览器结果只用于初筛;生产结论要在隔离环境用目标语言、并发和真实负载复测。

  • 自动补全全局标志

    表达式:\d+
    flags:空
    文本:a1 b22
    轮数:1000

    当前基准函数在未提供 g 时会自动加入 g;该样本每轮有 2 个匹配,耗时随浏览器和运行环境变化。

示例输出

  • 高风险回溯

    该近似失败输入触发嵌套量词回溯;耗时会随 a 的数量快速增长,应改写表达式并限制输入长度
  • 日志提取性能

    示例结果:1 次匹配,捕获 request_id=abc 与 latency=120ms;实际耗时取决于设备和运行次数
  • 长度增长与近似失败

    长度趋势:a×16!、a×32!、a×64! 逐步比较;达到安全上限即停止,不让页面冻结
  • 生产压测边界

    生产压测应记录 p50/p95/p99、超时、CPU、并发和最大输入长度,浏览器毫秒数不是服务端吞吐
  • 自动补全全局标志

    \d+ 在空 flags 下自动按 g 执行;文本 a1 b22 每轮得到 2 个匹配,1000 轮耗时随浏览器变化

常见错误

  • 浏览器里的基准结果只能代表当前 JS 引擎,不能直接推断所有后端语言表现。
  • 样本太短会掩盖性能问题,复杂正则要用接近生产长度的文本测试。
  • 只看平均耗时不看最坏输入,容易漏掉 ReDoS 风险。
  • 单次毫秒数只反映当前浏览器,不能直接推断服务端吞吐、SLA 或 ReDoS 安全性。
  • 近似失败样本应逐步增加长度并设置时间、长度和并发上限,不能为了追求极端数字让页面或服务失去响应。

适用场景

  • ReDoS 风险初筛
  • 日志规则优化
  • 表单校验性能检查
  • 正则方案对比

实操检查

  • 验证全局数字匹配

    固定输入:表达式 `\d+`、flags `g`、文本 `a1 b22`、轮数 `1000`。步骤:打开 Regex Benchmark,分别填写四个字段并点击“运行性能测试”。预期结果:结果区显示“每轮 2 个匹配”、1000 轮和非负毫秒数。失败判断:未显示 2 个匹配、出现 error,或轮数不是 1000。

  • 验证语法错误分支

    固定输入:表达式 `[`、flags `g`、文本 `abc`、轮数 `100`。步骤:填写字段并运行性能测试。预期结果:结果区出现 JavaScript RegExp 错误提示,且不显示正常基准卡片。失败判断:页面静默显示正常耗时,或错误结果仍报告匹配数。

页面专属核验

使用前与操作中

  • 先固定表达式、flags、输入文本和迭代次数;当前基准会确保使用 `g`,每轮重置 `lastIndex`,统计每轮 matchAll 的匹配数和浏览器耗时。
  • 用正常、最长合法、近似失败和长度递增样本比较趋势,尤其关注嵌套量词与歧义分支;不要把一次 `elapsedMs` 当作稳定的生产指标。
  • 浏览器基准只反映当前 JavaScript 引擎和当前设备;服务端 ReDoS 风险仍需在目标语言、并发、输入上限和超时策略下复测。

结果出来后

  • 无效表达式是否进入错误结果,合法表达式的 `matchesPerRun` 是否与实际全局匹配数量一致,而不是只看耗时?
  • 同一表达式在短文本、近似失败长文本和多次重复运行时,耗时趋势是否可复现,并排除了输入长度与迭代次数变化的影响?
  • 候选规则是否已经在目标运行时用并发、超时、长度限制和真实负载验证,且高回溯结构有可回滚的改写方案?

相关工具

  • 正则测试器:测试正则表达式、匹配结果和分组
  • 正则解释器:拆解正则元素,并用 AI 解释匹配逻辑、测试用例和误匹配风险
  • 正则风格转换:转换 JavaScript、Python、Java 的常见正则语法差异
  • 文本对比:按行对比文本、配置、日志和接口响应差异

工具边界

  • 基准结果受浏览器、设备、输入长度和运行次数影响,不能作为生产 SLA。
  • 单一平均耗时无法覆盖最坏输入、并发请求、内存占用和服务端超时。
  • 工具不能替代代码审查、依赖安全扫描、流量压测和真实日志回放。

与相似工具的区别

  • 正则测试器:Benchmark 重复运行并关注耗时与近似失败输入;普通测试器更适合查看单次匹配和捕获内容。

安全与兼容性

  • 基准仅在当前浏览器 JavaScript 引擎执行,不得把毫秒数直接当作服务端容量或 SLA。
  • 测试恶意长输入时应逐步增加长度并设置上限,避免让灾难性回溯冻结页面或开发环境。

下一步排查

  1. 准备正常、空值、超长、近似匹配失败和恶意输入样本。
  2. 结合正则解释器和风格工具定位嵌套量词、回溯分支及引擎差异。
  3. 在目标服务设置输入长度、执行超时和监控告警,并用真实流量样本复测。

常见问题

浏览器里的耗时就是生产耗时吗?

不是。它只反映当前浏览器和输入样本,后端语言、引擎、并发和超时配置可能完全不同。

为什么要测试最坏输入?

很多回溯问题在普通样本上不明显,但在接近匹配又最终失败的长文本上会急剧变慢。

发现耗时高应该怎么处理?

先减少嵌套量词和歧义分支,限制输入长度,必要时改用结构化解析或安全的 RE2 类引擎。

为什么不能只看一次耗时?

单次结果会受 JIT、设备、输入长度和页面负载影响;应重复运行并比较长度增长、最坏输入和分位耗时趋势。