正则表达式测试工具
实时测试和调试正则表达式,高亮匹配结果并生成代码
什么是正则表达式?
正则工具用于编写、测试和理解正则表达式。正则表达式通过模式描述文本,可用于搜索、提取、校验和替换,例如类似邮箱的字符串、日志字段、URL、ID、日期或重复格式。测试工具能在模式进入代码、数据处理流程或表单校验前,把匹配结果、捕获组、标志和边界情况直观展示出来。正则很强大,但也容易被过度依赖:模式可能匹配过多或过少,在大输入上变慢,或没有正确处理 Unicode 和本地化规则。复杂解析、HTML 结构或安全关键校验通常更适合专门的解析器或库。
使用方法
使用步骤
- 在左侧输入框中输入正则表达式模式
- 按需勾选标志(如 g 表示全局匹配,i 表示不区分大小写)
- 在右侧输入测试文本
- 查看高亮的匹配项及详情
正则表达式技巧
- 用匹配和不匹配的示例分别测试,更容易发现过于宽泛的表达式。
- 在长文本中慎用嵌套量词,部分模式可能因过度回溯而变慢。
使用场景
技术原理
测试器由 ECMAScript 语言规范中定义的 RegExp 引擎驱动。ECMAScript 正则表达式是一种回溯 NFA 实现:引擎从左到右尝试每个分支,当量词失败时回退,这使得环视和反向引用成为可能,但也是对抗性输入产生灾难性回溯的根源。引擎识别六个标志:g(全局)、i(不区分大小写)、m(多行,锚点按行匹配)、s(dotAll,'.' 匹配换行符)、u(Unicode 模式)和 y(粘性,锚定到 lastIndex)。 不同标志下的匹配语义差异很大。在 /u 模式下,引擎将模式视为 Unicode 码点序列而非 UTF-16 代码单元,因此代理对作为单个字符匹配,Unicode 属性类如 \p{L}(任意字母)、\p{Sc}(货币符号)和 \p{Script=Han}(汉字)也可使用。命名捕获组 (?<name>...) 和后行断言 (?<=...) 是 ES2018 的一部分,在 Chromium 64+、Firefox 78+ 和 Safari 16.4+ 中支持,但 PCRE 独有的特性如原子组 (?>...) 和占有量词 (a++) 尚未纳入规范。 生产环境中最大的隐患是 ReDoS——像 (a+)+b 这样的模式在输入 'aaaaaaaaaaaaaaaa!' 上会探索指数级数量的路径,因为两个嵌套量词可以用多种方式拆分同一段字符。缓解方法众所周知:避免对同一字符类使用嵌套量词,尽可能用 ^ 和 $ 锚定,在引擎支持时优先使用原子组,或切换到线性时间引擎如 Go 的 RE2(以失去反向引用和后行断言为代价换取 O(n) 的匹配保证)。对于需要服务端验证的不可信输入,RE2 或手写解析器几乎总是更安全的选择。
- 引擎:ECMAScript RegExp 是回溯 NFA,而非 DFA;这使得环视和反向引用成为可能,但也导致了灾难性回溯。
- 标志:g(全局)、i(不区分大小写)、m(^/$ 按行匹配)、s(dotAll,'.' 匹配 \n)、u(Unicode 模式,识别代理对)、y(粘性,锚定到 lastIndex)。
- Unicode 模式:/u 开启码点匹配并支持 \p{L}(字母)、\p{Sc}(货币)、\p{Script=Han}(汉字);不使用 /u 时,[a-zA-Z]+ 会遗漏所有非拉丁文字。
- 现代语法支持:命名捕获 (?<n>...) 和后行断言 (?<=...) 在 Chromium 64+、Firefox 78+、Safari 16.4+ 中支持;原子组 (?>...) 和占有量词 (a++) 不在 ECMAScript 规范中。
- ReDoS:对同一字符类使用嵌套量词如 (a+)+b 会指数级爆炸;可通过锚定、原子组收紧,或迁移到 RE2 / re2-wasm 处理不可信输入。
- 复杂度下限:对固定字母表的字面锚定模式以 O(n) 运行;反向引用和无界环视会将最坏情况推至指数级,因此发布前应在对抗性输入上进行基准测试。
示例
匹配邮箱地址
正则: ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$
标志: gi
输入: contact: alice@example.com, bob_2024@mail.co.uk, invalid@.com
匹配: alice@example.com, bob_2024@mail.co.uk (命中 2 个)从日志中提取 IPv4 地址
正则: \b(?:\d{1,3}\.){3}\d{1,3}\b
标志: g
输入: 2026-06-15 ERROR client 192.168.1.42 connect failed (peer 10.0.0.1)
匹配: 192.168.1.42, 10.0.0.1用具名分组捕获日期片段
正则: (?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})
标志: g
输入: Sprint window: 2026-09-01 to 2026-09-15
分组: {year:'2026', month:'09', day:'01'}, {year:'2026', month:'09', day:'15'}贪婪 vs 懒惰量词
输入: <b>hello</b> <i>world</i>
.* (贪婪)-> 匹配整行:<b>hello</b> <i>world</i>
.*? (懒惰)-> 只匹配第一段:<b>hello</b>
抓取标签之间的内容时,通常应当使用懒惰量词。支持 Unicode 的字母字符类
正则: \p{L}+
标志: gu
输入: Hello, 北京! Café Москва
匹配: Hello, 北京, Café, Россия
如果不加 u 标志、不用 \p{L},单纯的 [a-zA-Z]+ 会漏掉所有非拉丁文单词。常见问题
测试器使用的是哪种正则方言?
JavaScript 的正则引擎(ECMAScript)。在常见特性上与 PCRE 类似,但在边缘情况上有差异:不支持独占量词、不支持递归,后行断言需要较新的浏览器,命名分组语法是 (?<name>...)。在 Python(re/regex)、Java、.NET 或 PCRE 中,相同的模式可能表现不同——也建议在目标环境中实际测试。
支持哪些标志?
g(全局,匹配所有结果)、i(忽略大小写)、m(多行,^ 和 $ 匹配行边界)、s(dotall,. 匹配换行)、u(Unicode)、y(粘性)、d(hasIndices)。在工具栏切换即可,页面会展示每个标志在你的测试文本上带来的变化。
为什么我的模式匹配数量比预期少?
没加 g 标志时,regex.exec 一次只返回一个匹配;没加 m 时,^ 和 $ 只匹配整段输入的开头和结尾;没加 u 时,代理对字符(如 emoji)会被当成两半分别匹配。绝大多数「为什么不生效」的问题都是少了某个标志。
怎么匹配 emoji 和中日韩字符?
使用 u 标志开启正确的 Unicode 处理。通过 \p{...} 字符类(如 \p{Letter}、\p{Script=Han}、\p{Emoji})按 Unicode 属性匹配。不开启 u 时,[a-zA-Z] 不会匹配带音标的字符——可以扩展为 [a-zA-ZÀ-ÿ],或改用 \p{L}。
可以根据正则生成代码吗?
大多数版本可以将模式导出为 JavaScript、Python、PHP、Ruby、Go 或 Java 语法,并自动处理转义。需要注意:同一模式在不同引擎下可能表现不同(贪婪默认值、字符类行为、环视支持等),最终请务必在目标语言中测试。
贪婪量词和懒惰量词有什么区别?
贪婪(* + ?)尽可能多匹配,必要时回溯;懒惰(*? +? ??)尽可能少匹配。比如「提取 A 和 B 之间的内容」,若文本里有多个 B,贪婪的 .* 会匹配过头,而懒惰的 .*? 会停在第一个 B 之前。提取内层内容时,默认推荐用懒惰。
我的正则或测试文本会上传吗?
不会。匹配在你的浏览器里使用 JavaScript 原生正则引擎完成,模式与输入都不会被传输。