正则表达式测试器 — 在线测试正则表达式
这个正则表达式测试器支持实时编写、测试和调试正则表达式。输入模式和测试字符串,即可查看带有高亮匹配项、捕获组和匹配详情的实时结果,适用于 JavaScript 正则表达式。
正则表达式测试器
在一个地方测试模式、查看匹配结果并尝试替换。
常见问题
什么是正则表达式(regex)?
正则表达式(regex或regexp)是定义搜索模式的字符序列。它用于字符串内的模式匹配——查找符合特定结构的文本、验证输入格式以及执行搜索替换操作。几乎每种编程语言都支持正则表达式,包括JavaScript、Python、Java、Go和许多文本编辑器。
最常用的正则表达式模式是什么?
最常用的正则表达式模式包括:邮件验证([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})、URL匹配(https?://[\w.-]+)、电话号码(\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4})、IP地址、ISO格式日期(\d{4}-\d{2}-\d{2})、十六进制颜色代码(#[0-9a-fA-F]{3,6})以及整数或小数匹配。
什么是正则表达式中的捕获组?
捕获组是正则表达式模式中用括号括起来的部分()。当正则表达式匹配时,每个组捕获其匹配的文本,可以在后面引用。例如,(\d{4})-(\d{2})-(\d{2})匹配"2026-03-22"时创建三个捕获组:$1="2026"、$2="03"、$3="22"。命名组使用语法(?<name>...)使代码更清晰。非捕获组(?:...)进行分组但不捕获。
什么是前瞻和后顾断言?
前瞻和后顾是零宽度断言,在不将其包含在匹配中的情况下检查模式。正向前瞻(?=abc)匹配后面跟着"abc"的位置。负向前瞻(?!abc)匹配后面不跟"abc"的位置。正向后顾(?<=abc)匹配前面是"abc"的位置。负向后顾(?<!abc)匹配前面不是"abc"的位置。它们对于复杂的条件匹配非常有用。
贪婪匹配和懒惰匹配有什么区别?
贪婪量词(*、+、?)尽可能多地匹配文本,而懒惰量词(*?、+?、??)尽可能少地匹配。例如,给定字符串"<b>bold</b>",贪婪模式<.*>匹配整个字符串"<b>bold</b>",但懒惰模式<.*?>只匹配"<b>"。当您想要最短可能的匹配时,使用懒惰量词。
什么是灾难性回溯?
当正则表达式引擎需要指数级时间来确定字符串不匹配某个模式时,会发生灾难性回溯。这发生在嵌套量词如(a+)+或具有重叠替代项的模式中。引擎在失败前尝试每种可能的组合,导致极度缓慢或卡死。通过使用具体字符类、原子组和限制重复范围来避免这种情况。
正则表达式标志(修饰符)有什么作用?
正则表达式标志修改模式的解释方式。常见标志包括:g(全局)——查找所有匹配而不仅仅是第一个;i(不区分大小写)——忽略大小写差异;m(多行)——^和$匹配行边界而不是字符串边界;s(dotall)——.字符匹配换行符;u(Unicode)——启用完整Unicode匹配。标志可以组合使用,例如/pattern/gim。
如何在线测试正则表达式?
在模式字段中输入正则表达式,在下方的文本区域粘贴测试字符串。匹配结果会在您输入时实时高亮显示。使用标志按钮切换标志(g、i、m、s、u)。在匹配面板中查看包括索引位置和捕获组在内的匹配详情。使用替换部分测试替换模式,并浏览常见模板以获取预置模式。
正则表达式替换中的反向引用如何工作?
在正则表达式替换中,反向引用允许您在替换字符串中重用捕获组。使用$1、$2等引用编号捕获组,或$<name>引用命名组。例如,将(\w+)\s(\w+)替换为$2 $1会交换两个单词。在替换字符串中,$&引用整个匹配,$`引用匹配前的文本,$'引用匹配后的文本。
正则表达式和通配符模式有什么区别?
通配符模式是主要用于Shell中文件路径匹配的简单通配符模式(例如*.txt、src/**/*.js)。它们支持*(任意字符)、?(单个字符)和[...](字符类)。正则表达式更为强大,支持量词、锚点、分组、交替、前瞻和后顾以及反向引用。正则表达式可以操作任何字符串内容,而通配符通常限于路径匹配。
关于正则表达式
正则表达式(regex)是用于匹配、搜索和处理文本的强大模式语言。它提供了一套简洁的字符序列描述方式,涵盖简单的字面量匹配,以及涉及重复、分支、分组和零宽断言的复杂模式。几乎所有编程语言和文本编辑器都支持正则表达式,是开发者、数据分析师和系统管理员的必备工具。
本正则表达式测试器支持实时编写、测试和调试正则表达式。在你输入模式和测试字符串时,匹配项会即时高亮显示,捕获组会自动提取,执行时间也会同步测量。你还可以使用反向引用执行查找替换操作。
正则表达式语法速查
字符类
| 模式 | 说明 |
|---|---|
[abc] | 匹配 a、b 或 c 中的任意一个字符 |
[^abc] | 匹配除 a、b、c 以外的任意字符 |
[a-z] | 匹配 a 到 z 范围内的任意字符 |
\d | 匹配任意数字(等价于 [0-9]) |
\D | 匹配任意非数字字符 |
\w | 匹配任意单词字符(字母、数字、下划线) |
\W | 匹配任意非单词字符 |
\s | 匹配任意空白字符(空格、制表符、换行符) |
\S | 匹配任意非空白字符 |
. | 匹配除换行符以外的任意字符(设置 s 标志后也匹配换行符) |
量词
| 模式 | 说明 |
|---|---|
* | 匹配 0 次或多次(贪婪) |
+ | 匹配 1 次或多次(贪婪) |
? | 匹配 0 次或 1 次(贪婪) |
{n} | 精确匹配 n 次 |
{n,} | 匹配 n 次或更多次 |
{n,m} | 匹配 n 到 m 次 |
*? | 匹配 0 次或多次(懒惰/非贪婪) |
+? | 匹配 1 次或多次(懒惰/非贪婪) |
锚点
| 模式 | 说明 |
|---|---|
^ | 匹配字符串开头(使用 m 标志时匹配行首) |
$ | 匹配字符串结尾(使用 m 标志时匹配行尾) |
\b | 匹配单词边界 |
\B | 匹配非单词边界 |
分组与零宽断言
| 模式 | 说明 |
|---|---|
(abc) | 捕获组——匹配"abc"并保存结果 |
(?:abc) | 非捕获组——分组但不保存 |
(?<name>abc) | 命名捕获组 |
\1 | 对第 1 个捕获组的反向引用 |
a|b | 分支——匹配 a 或 b |
(?=abc) | 正向前瞻——匹配后面跟着"abc"的位置 |
(?!abc) | 负向前瞻——匹配后面不跟"abc"的位置 |
(?<=abc) | 正向后顾——匹配前面是"abc"的位置 |
(?<!abc) | 负向后顾——匹配前面不是"abc"的位置 |
常用正则表达式模式
以下是实际开发中常用的正则表达式模式:
- 邮件地址验证 —
[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}匹配标准电子邮件地址 - URL 匹配 —
https?://[\w.-]+(?:\.[\w.-]+)+[\w.,@?^=%&:/~+#-]*匹配 HTTP 和 HTTPS 链接 - IP 地址 —
\b(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\b验证 IPv4 地址 - 日期(ISO 格式) —
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])匹配 YYYY-MM-DD 格式日期 - 十六进制颜色 —
#(?:[0-9a-fA-F]{3}){1,2}\b匹配 #RGB 和 #RRGGBB 颜色代码 - 密码强度 —
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}要求包含大写字母、小写字母、数字和特殊字符(至少 8 位)
各编程语言中的正则表达式
正则表达式的核心语法在各编程语言中大体相同,但在功能支持、转义规则和接口用法上存在明显差异:
| 特性 | JavaScript | Python | Java | Go |
|---|---|---|---|---|
| 引擎 | V8/SpiderMonkey | re 模块 | java.util.regex | RE2 |
| 零宽断言 | 支持 | 支持 | 支持 | 不支持 |
| 命名捕获组 | (?<name>...) | (?P<name>...) | (?<name>...) | (?P<name>...) |
| 反向引用 | \1 或 $1 | \1 或 \g<1> | \1 或 $1 | 不支持 |
| 回溯 | 支持 | 支持 | 支持 | 不支持(RE2 为线性引擎) |
| 示例 | /\d+/g.test(s) | re.findall(r'\d+', s) | Pattern.compile("\\d+") | regexp.MustCompile(`\d+`) |
正则表达式性能优化技巧
写法不当的正则表达式可能引发灾难性回溯,导致引擎处理某些输入时耗费指数级时间。以下建议可帮助你编写高效的正则表达式:
- 避免嵌套量词 —
(a+)+或(a*)*这类模式在不匹配的输入上会引发指数级回溯,应简化为a+ - 使用原子组或占有型量词 — 在支持的引擎中,
(?>...)可阻止引擎回溯到已匹配的组内 - 精确使用字符类 — 当你明确知道期望的字符范围时,用
[a-z]代替.,范围更窄的字符类可减少不必要的匹配尝试 - 添加锚点 — 匹配完整字符串时加上
^和$,防止引擎逐位置尝试 - 适时使用非贪婪量词 —
.*?在找到第一个匹配后即停止,而非消耗整个字符串再回溯 - 限制重复次数上限 — 用
{1,100}代替+,限制迭代次数,防止匹配失控 - 使用对抗性输入测试 — 始终用接近匹配但不完全匹配的长字符串测试你的正则表达式,在上线前发现潜在的回溯问题