开发
测试正则表达式
匹配结果就地高亮,同时列出位置偏移,你能一眼看出这个模式匹配的是你真正想要的东西,还是只是你写出来的东西。
怎么用
- 输入模式,不要带首尾的斜杠。
- 在小输入框里写标志:g 全部、i 忽略大小写、m 多行。
- 把要测试的文本粘贴到下面。
- 看匹配列表——每一行显示捕获组和字符位置。
灾难性回溯
像 (a+)+$ 这样的模式,拿去匹配三十个 a 后面跟一个 b,耗时会呈指数增长——因为引擎会尝试把那些 a 在两个量词之间所有可能的分配方式,才得出「不匹配」。这就是单个请求能把 CPU 打满的原理:这种手法叫 ReDoS,是真实的拒绝服务攻击面。嵌套量词和有歧义的分支是常见元凶。
写出人能读的正则
用明确的字符类而不是裸点号,语法允许的地方给分组起名,长模式用扩展标志换行拆开。花一小时写出来的模式,半年后调试要花一天,而这份成本落在接手代码的人身上——通常不是你。
一块一块地搭出正则
先写出能匹配一个已知正确样例的最小模式,确认它能过,再加入下一个约束。一次写完的模式,出错时很难归因:量词位置放错和字符类写错,结果都只是「不匹配」,没有任何提示。
两个习惯最省时间。如果要匹配整串,就加 ^ 和 $ 锚定——没锚定的邮箱模式会愉快地匹配到四百行文字里夹着的一个邮箱。另外,一定要拿一个不该匹配的字符串来测:一个只见过合法输入的模式,不叫被测过,叫被装饰过。
常见问题
为什么标志框默认是 g?
因为测试正则通常就是要找出全部匹配。只想要第一个就去掉它;为了让高亮正常工作,工具内部仍会补上 g。
支持后行断言吗?
支持,只要浏览器实现了 ES2018 的 lookbehind——现在的 Chrome、Firefox、Safari 都支持。不支持的语法会直接报引擎错误,而不是静默失败。
结果里的 $1、$2 是什么?
是捕获组,编号按左括号出现的顺序。在替换字符串里引用它们就能重排匹配到的内容。
匹配数量有上限吗?
高亮最多迭代 5000 次以保证页面不卡,表格只列出前 60 条。对正常测试来说绰绰有余。
为什么同一个正则在某门语言里能用,换个语言就不行?
方言不同:JavaScript 没有占有量词和原子组,Python 有;后行断言在 JavaScript 里必须是定长,在 Python 和 PCRE 里不必。
输入长度有安全上限吗?
没有通用数字,但「几十万字符以上的输入」加上「嵌套量词」就是会冻住标签页的组合。该限制的是输入,不是模式。