正则表达式测试器
用你自己的文本测试正则表达式:高亮每一处匹配与捕获组、逐段解释表达式里每个部分的含义,并对照 JavaScript / PCRE / RE2 三家引擎的支持差异。全部在你的浏览器里计算。
同时提供 Windows 桌面版。
关于这个工具
正则表达式是一门描述文本形态的迷你语言,几乎所有处理文本的工具都说这门语言 —— 搜索框、日志筛选、代码编辑器、数据库查询。它也是出了名的"写起来像对的,匹配结果却是错的"。解法不是硬想,而是拿一段你**已经知道答案**的文本让它跑一遍,看它到底匹配到了什么。
这一页把这件事收在一个地方。输入表达式、勾选标志、贴上文本,每一处匹配都会就地高亮,每一个捕获组连同它在文本里的位置一起列在下面。再往下,表达式会被拆成一个个片段逐个解释 —— 你就能看清 \b、(?<=…) 和懒惰量词各自到底在干什么,不用再去翻速查表。
第三个区块讲的是大多数测试器都忽略的一件事:同一个表达式在不同引擎里表现并不一致。在浏览器里跑得好好的正则,搬到服务端的 RE2 上可能直接被拒,也可能行为悄悄变了。那张对照表列出的是引擎之间**真正有分歧**的那些特性,好让你本地能跑的正则,别在生产环境里给你惊喜。
所有计算都在你自己的设备上完成。没有上传这一步,也没有哪台服务器在替你匹配 —— 当你测的是一行客户资料或者一段生产日志时,这一点很重要。
常见问题
- 为什么我的表达式算不完?
- 有些表达式会爆炸式回溯。(a+)+$ 配上一长串 a 是经典例子:每多一个字符,计算量大约翻一倍,四十个字符就已经是一万亿步了。本工具把表达式放在独立线程里跑,超时就直接中止,所以页面不会失去响应。看到那句提示,说明问题出在表达式本身 —— 通常是量词嵌套,或者两个量词能匹配同一段文本。
- 贪婪和懒惰有什么区别?
- 量词默认是贪婪的:先尽量多取,然后一个字符一个字符吐回来,直到表达式剩下的部分能对上为止。加上 ? 就变成懒惰:先尽量少取,实在不够了再往外扩。对 <b>bold</b> 来说,<.+> 会匹配整串,而 <.+?> 只匹配 <b>。两个都对 —— 它们回答的是不同的问题。
- \w 能匹配中文或者带重音的字母吗?
- 在 JavaScript 里不能 —— 除非开了 u 标志,否则 \w 只等于 ASCII 的字母、数字和下划线。中文、西里尔字母、带重音的拉丁字母、emoji 全都不在里面。如果你想把任意文字系统的字母都当作单词字符,用带 u 标志的 \p{L},或者把你真正要的那些范围列出来。
- 先行断言和后行断言是干什么的?
- 它们让你"要求某个东西存在,但不把它算进匹配结果"。"250 dollars" 里,\d+(?= dollars) 匹配的是数字 250,不含 dollars 这个词 —— 匹配结果就是 250。后行断言朝前看:(?<=\$)\d+ 取出美元符号后面的数字,但不含这个符号。这是表达"只有被某物包围时才匹配"的标准做法,也正是 RE2 做不到的地方。
- 为什么我的表达式只返回一个结果?
- 因为没开 g 标志。没有 g 时,表达式匹配到第一个就停了 —— 这是 JavaScript 和大多数语言的默认行为。打开 g 它才会继续找下去。如果你是从某个搜索框过来的,那里能列出全部结果,是因为那个框替你把 g 开好了。
- 我粘贴的文本会被发到服务器吗?
- 不会。匹配在你的浏览器里、在你的机器上的一个工作线程里完成,你输入的任何一个字都不会被传输或记录。这是刻意的:人们最常拿来试正则的,就是生产日志的某一行和客户数据,这两样都不该出现在别人的服务器上。
- 粘性标志 y 是干什么的?
- 它把每一次匹配都钉在上一次匹配结束的那个确切位置上,而不是从那里继续往后搜。你可以靠它把一段字符串逐段走完,并在表达式不再匹配时立刻知道。PCRE 里有同一个东西,名字叫 \G —— 所以对照表把它们列在了一起。