正则测试
实时测试和调试正则表达式,支持匹配高亮显示。
匹配结果
0 matches未找到匹配项。
实时测试和调试正则表达式,支持匹配高亮显示。
未找到匹配项。
模式和测试文本
\b(\w+)\s+\1\b
This is is a test匹配结果
is is在生产环境使用正则前,应同时测试有代表性的正确与错误输入。
正则表达式测试工具让你先写好模式、粘贴一段测试文本,立刻看清到底匹配了什么:命中处就地高亮,捕获组逐条列出,确认无误后再把表达式放进业务代码。输入时匹配结果实时刷新,你可以反复打磨模式,而不是改一次代码跑一遍应用。它面向编写校验规则的开发者、从日志里抽取字段的分析师,以及任何想弄明白 \b\w+@\w+\.\w+\b 这类表达式究竟会命中什么的人。
示例一——邮箱格式的快速体检。 用 ^[^\s@]+@[^\s@]+\.[^\s@]+$ 匹配 ada@example.com 会命中;匹配 ada@example 则不命中,因为末尾的 \.[^\s@]+ 要求必须有一个点和至少一个后续字符。把通过与不通过的样本放在同一个面板里测试,就能直观看到模式到底接受和拒绝了什么。
示例二——从日志里提取网址。 把 https?://[^\s"'<>]+ 跑在日志行上,每个网址会依次高亮。反向字符类 [^\s"'<>]+ 在第一个空白或引号处停下,避开了贪婪匹配把整行剩余内容一口吞掉的经典问题。
示例三——调试捕获组。 对电话模式 ^\+?(\d{1,3})[-.\s]?(\d{3})[-.\s]?(\d{4})$,分组面板会显示第 1 组是国家代码,第 2、3 组是本地号码段。若某个分组返回空值,通常是它周围的可选元素没匹配上——在分组列表里一眼就能看到。
匹配就是引擎接受的那段子串。括号会创建捕获组:每一对括号记录它所包裹的那部分匹配,按左括号从左到右编号。捕获组让你提取片段而不只是判断存在与否——从电话号码里取出区号,从日志行里取出键,从网址里取出路径。
实践中有两种细化写法值得掌握。命名组写成 (?<year>\d{4}),在结果里按名字而不是编号出现,长模式的可读性会好很多。非捕获组写成 (?:...),用来给量词分组或归纳多个可选项,却不占用编号;当 (cat|dog)+ 的重点是重复而不是捕获时就用它。
交替和锚点补齐了整套工具:| 在多个选项之间择一,^ 和 $ 把匹配钉在行边界(配合多行标志),\b 标记单词边界,避免模式命中更长的词内部。
A 和 a 视为等价。^ 和 $ 匹配每一行的首尾,而非整段字符串的首尾。. 匹配换行符,默认情况下它拒绝匹配换行。".*" 会从文本的第一个引号一直匹配到最后一个引号。改用 ".*?" 才是最短匹配。\.;在字符类里 [.] 也可以,而且更易读。+、*、?、(、)、[、]、{ 同理。(a+)+ 这类嵌套量词在近乎匹配的输入上可能冻结引擎,改用反向字符类或把模式锚定得更紧。^/$。 它们只匹配整段字符串的首尾,逐行校验会悄悄失效。g 标志的正则会保留 lastIndex;重复使用同一对象可能跳过匹配,记得重置或每次新建。u 标志时 . 匹配单个 UTF-16 编码单元,emoji 可能被从中间劈开。文本含辅助平面字符时请启用 u。JavaScript(ECMAScript)正则,由浏览器自身的引擎求值。这也是 Node.js、Chrome 以及所有前端框架里用的同一套语法,所以在这里验证通过的模式拿到应用代码里行为一致;而像递归、占有量词这类 PCRE 专有特性,JavaScript 并不支持。
绝大多数情况是贪婪量词造成的。* 和 + 默认尽可能多地吃字符,引擎回溯后才收手。在量词后加问号改成懒惰模式(.*?),匹配就会在最近的结束符处停下,而不是最远的那一个。用 [^>]* 这类反向字符类通常更快也更清晰。
测试文本里每个匹配都会被就地高亮。面板按顺序列出每个匹配捕获到的分组:第 1 组、第 2 组……未命名的组用编号显示。写成 (?<name>...) 的命名组按名字展示;非捕获组 (?:...) 参与匹配但不列入结果,只想要分组而不需要捕获时很方便。
g 找出全部匹配而不是遇到第一个就停;i 忽略大小写;m 让 ^ 和 $ 匹配每一行的行首行尾,而不只是整段文本的首尾;s 允许点号匹配换行。u 启用 Unicode 感知匹配,当文本可能包含 emoji 或非拉丁文字时应打开。y 把每次匹配锚定在上一次结束的位置,编写解析器时偶尔会用到。
会——灾难性回溯。像 (a+)+ 或 (.*)* 这种嵌套量词,在「几乎匹配」却不匹配的输入上,耗时可能呈指数增长。若测试器失去响应,刷新页面并简化模式,通常是把嵌套量词换成反向字符类,或把模式锚定得更紧。
带 g 标志的正则对象会在两次调用之间保留 lastIndex,重复使用同一个对象时,下一次匹配会从上次结束的位置继续,从而跳过前面的结果。重新匹配前把 lastIndex 归零,或者每次测试都新建一个正则对象。
由 HandyTools Hub 团队审校 · 最后更新