正则表达式测试工具

实时高亮测试正则表达式,查看捕获组与替换预览。匹配在 Web Worker 中执行并设有时限,失控的表达式不会冻结页面。

所有处理均在你的浏览器内完成,数据不会上传。

匹配结果 (0)

没有匹配。

匹配在 Web Worker 中执行并设有时限。JavaScript 的正则一旦开始就无法中断,失控的表达式会冻结整个页面——多数在线正则工具正是如此。

使用方法

  1. 在上方输入表达式,不需要写两侧的斜杠。
  2. 按需切换标志。g 默认开启;不开的话只会找到第一个匹配。
  3. 粘贴测试文本,匹配会随输入实时高亮。
  4. 填写替换内容可预览结果——$1 引用编号组,$<name> 引用命名组。

关于正则表达式,以及那个真正会咬人的地方

正则描述的是一种模式而非固定字符串,匹配引擎的工作方式是不断尝试各种可能,失败了就回退 重来。这种回溯正是正则表达力的来源,也是唯一一个值得真正理解的失效模式的根源。

(a+)+b 匹配 aaaaaaaaaaaaaaaaaaaaaaaaaaaa 为例。字符串里没有 b,匹配注定失败—— 但在得出这个结论之前,引擎会尝试把这些 a 在内外两层量词之间切分的每一种方式。每多一个 字符,切分方式就翻一倍,到三十个 a 时引擎要走过数以亿计的可能。这就是灾难性回溯, 它确实搞垮过生产系统:日志解析规则里的一条正则遇上一行异常输入,是有据可查的事故模式。

而它在浏览器里格外危险的原因是:JavaScript 无法中断正在运行的正则。没有超时参数、 没有取消机制、其他代码也拿不到执行权。一个在主线程上回溯的表达式会让标签页彻底冻住—— 不能滚动、不能点击、也停不下来。多数在线正则工具都是这么做的,于是一个用来做实验的表达式, 能把你正在做实验的那个页面本身弄死。

本工具把匹配放在 Web Worker 里执行并设有时限。Worker 是独立线程,它工作时页面保持 响应;超过时限仍未结束,整个 Worker 会被终止。这个终止是唯一可靠的止损手段——没有任何 办法能让一段正在回溯的正则自己停下来。

结果上方那个形状提示是一个启发式判断,它查找嵌套量词。它刻意不做拦截:一个表达式是否真的 会爆炸取决于输入,而严格判定这件事在一般情况下不可判定。提示告诉你该往哪里看,真正保护你 的是超时。

常见问题

为什么要把匹配放到后台线程里执行?

因为 JavaScript 的正则一旦开始就无法中断。像 (a+)+b 这样的模式,遇到「几乎能匹配」的文本会花费指数级时间,跑在主线程上就意味着标签页彻底冻结,除了关掉别无他法。放进 Web Worker 后页面保持响应,超时还能把它整个掐掉。在正则工具里这尤其不是杞人忧天:半成品的表达式恰恰就是会灾难性回溯的那种形状,而测试的过程中你会写下大量半成品。

这里用的是哪种正则方言?

JavaScript 的,因为它直接用你浏览器里现成的引擎。大部分语法是跨语言通用的,但确实有差异:JavaScript 没有占有量词和原子组,后行断言支持得比较晚,而 \\d 在不考虑 Unicode 时只匹配 ASCII 数字。如果这个表达式最终要用在 Python、PCRE 或 Go 里,棘手的部分请再到那门语言里验一遍。

为什么只匹配到一个,我以为会有好几个?

g 标志没开。不加 g 时匹配到第一个就停——这是语言本身的行为,不是本工具的限制。打开 g 即可收集全部匹配。

m 和 s 这两个标志有什么区别?

它们常被弄混,因为都和换行有关。m 改变的是 ^ 和 $ 的含义:加上它,两者匹配每一行的开头和结尾,而不只是整个字符串的首尾。s 改变的是 . 的含义:加上它,点号也能匹配换行符,否则它永远不匹配换行。两者相互独立,你可能只需要其中一个、两个都要,或都不要。

我的文本会被发送到别处吗?

不会。表达式和文本都留在你的浏览器里。这一点值得知道,因为调试正则时经常会粘进生产数据——日志行、真实邮箱、样本记录——好让测试贴近实际。

我的表达式明明能用,为什么被标为「有风险」?

那个提示是形状层面的启发式判断:它查找 (a+)+ 这类嵌套量词,也就是灾难性回溯最常见的成因。一个表达式究竟会不会爆炸取决于输入,所以被标记的模式可能在你的测试文本上瞬间完成,却在更长的文本上卡死。严格判定这件事在一般情况下是不可判定的,所以真正的保护是超时,而不是这个提示。