什么是正则表达式
正则表达式(Regular Expression,简称 regex 或 regexp)是一种用于匹配字符串中字符模式的强大工具。它用一套简洁的语法规则,描述复杂的文本搜索、替换和提取需求,是每位开发者都应掌握的核心技能之一。
定义与用途
简单来说,正则表达式是一串字符,它定义了一个搜索模式。你可以用这个模式来:
- 验证用户输入是否符合格式(邮箱、手机号、密码强度)
- 从长文本中提取特定信息(URL、日期、数字)
- 批量替换文本中的某些内容
- 拆分字符串为有意义的片段
- 在代码编辑器中进行高级搜索
无论是前端表单验证、后端数据清洗,还是日常文本处理,正则表达式都能大幅提升效率。
历史背景
正则表达式的概念最早可追溯到 20 世纪 50 年代,由数学家 Stephen Kleene 提出。1970 年代,Ken Thompson 将其引入 Unix 系统的 ed 编辑器和 grep 工具中,从此成为程序员的标配工具。如今,几乎所有主流编程语言(JavaScript、Python、Java、Go 等)都内置了正则表达式支持。
正则表达式基础语法
正则表达式的语法虽然看起来像"天书",但核心元素并不多。掌握下面这些基础构件,你就能读懂和编写绝大多数正则表达式。如果某个 pattern 看起来仍然像天书,把它贴进正则表达式解析器逐段拆解即可。
字面量字符
最基础的正则表达式就是普通字符本身,它们精确匹配自己:
hello
这个模式会匹配字符串中出现的 "hello"。
元字符
元字符是正则表达式中具有特殊含义的字符,它们是构建复杂模式的基石:
| 元字符 | 含义 |
|--------|------|
| . | 匹配除换行符外的任意单个字符 |
| * | 匹配前面的元素零次或多次 |
| + | 匹配前面的元素一次或多次 |
| ? | 匹配前面的元素零次或一次 |
| ^ | 匹配字符串的开头 |
| $ | 匹配字符串的结尾 |
| \ | 转义字符,让后面的元字符恢复字面含义 |
| \| | 或运算,匹配左边或右边的表达式 |
| ( ) | 分组,将多个元素组合成一个单元 |
| [ ] | 字符类,匹配方括号内的任意一个字符 |
| { } | 量词,指定前面元素的匹配次数 |
如果要匹配元字符本身,需要用反斜杠转义,比如 \. 匹配点号,\$ 匹配美元符号。
字符类
字符类用于匹配某一类字符,是最常用的功能之一:
| 字符类 | 含义 | 等价写法 |
|--------|------|----------|
| \d | 匹配任意数字 | [0-9] |
| \w | 匹配字母、数字、下划线 | [a-zA-Z0-9_] |
| \s | 匹配空白字符(空格、制表符、换行符等) | [ \t\n\r\f] |
| \D | 匹配非数字字符 | [^0-9] |
| \W | 匹配非单词字符 | [^a-zA-Z0-9_] |
| \S | 匹配非空白字符 | [^ \t\n\r\f] |
你也可以用方括号自定义字符类:
[aeiou]:匹配任意一个元音字母[a-z]:匹配任意小写字母[A-Z]:匹配任意大写字母[0-9]:匹配任意数字[^aeiou]:匹配非元音字母(^在方括号内表示取反)
量词
量词控制前面的元素应该出现多少次:
| 量词 | 含义 |
|------|------|
| * | 零次或多次(贪婪) |
| + | 一次或多次(贪婪) |
| ? | 零次或一次(贪婪) |
| {n} | 恰好 n 次 |
| {n,} | 至少 n 次 |
| {n,m} | n 到 m 次 |
示例:
a{3}匹配 "aaa"\d{4}匹配四位数字a{2,4}匹配 2 到 4 个 aa{2,}匹配至少 2 个 a
锚点
锚点不匹配具体字符,而是匹配位置:
| 锚点 | 含义 |
|------|------|
| ^ | 字符串开头 |
| $ | 字符串结尾 |
| \b | 单词边界 |
| \B | 非单词边界 |
示例:
^Hello匹配以 "Hello" 开头的字符串world$匹配以 "world" 结尾的字符串\bword\b匹配独立的单词 "word",不会匹配 "sword" 中的 "word"
分组与捕获
用圆括号 ( ) 可以把多个元素组合成一个整体,同时还能捕获匹配的内容供后续使用。
(ab)+
这个模式匹配 "ab" 重复一次或多次,如 "ab"、"abab"、"ababab"。
如果你只需要分组而不需要捕获,可以用非捕获分组:
(?:ab)+
(?: ) 表示只分组不捕获,性能略好,也不会占用捕获组编号。
反向引用
捕获的内容可以用 \1、\2 等在正则表达式内部引用,数字对应捕获组的顺序:
(\w+)\s+\1
这个模式匹配重复的单词,比如 "hello hello"。\1 引用第一个捕获组匹配的内容。
环视
环视(Lookaround)是一种高级特性,它匹配位置而不消耗字符,分为四种:
| 语法 | 名称 | 含义 |
|------|------|------|
| (?=...) | 正向前瞻 | 后面必须是 |
| (?!...) | 负向前瞻 | 后面必须不是 |
| (?<=...) | 正向后顾 | 前面必须是 |
| (?<!...) | 负向后顾 | 前面必须不是 |
示例:
\d+(?=元)匹配后面跟着"元"的数字\d+(?!元)匹配后面不跟着"元"的数字(?<=¥)\d+匹配前面是"¥"的数字(?<!¥)\d+匹配前面不是"¥"的数字
修饰符(flags)
修饰符改变正则表达式的匹配行为,常用的有:
| 修饰符 | 名称 | 作用 |
|--------|------|------|
| g | global | 全局匹配,找到所有匹配项而不是第一个 |
| i | ignoreCase | 忽略大小写 |
| m | multiline | 多行模式,^ 和 $ 匹配每行的开头和结尾 |
| s | dotAll | 让 . 也能匹配换行符 |
| u | unicode | Unicode 模式,正确处理 Unicode 字符 |
在 JavaScript 中,修饰符写在正则字面量的末尾:
const regex = /hello/gi;
常见场景示例
下面是一些实际开发中经常用到的正则表达式模式。
邮箱验证
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
这个模式验证标准邮箱格式:用户名@域名.后缀。
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
emailRegex.test("user@example.com"); // true
emailRegex.test("invalid-email"); // false
手机号验证
^1[3-9]\d{9}$
中国大陆手机号验证:以 1 开头,第二位是 3-9,总共 11 位数字。
const phoneRegex = /^1[3-9]\d{9}$/;
phoneRegex.test("13812345678"); // true
phoneRegex.test("12345678901"); // false
URL 匹配
https?:\/\/[^\s]+
匹配 http 或 https 开头的 URL。
const urlRegex = /https?:\/\/[^\s]+/g;
const text = "访问 https://example.com 和 http://test.org 获取更多信息";
text.match(urlRegex);
// ["https://example.com", "http://test.org"]
HTML 标签提取
<(\w+)[^>]*>([\s\S]*?)<\/\1>
匹配成对的 HTML 标签并捕获标签名和内容。
const htmlRegex = /<(\w+)[^>]*>([\s\S]*?)<\/\1>/g;
const html = "<div>Hello <b>World</b></div>";
html.match(htmlRegex);
// ["<div>Hello <b>World</b></div>", "<b>World</b>"]
密码强度校验
至少 8 位,包含大写字母、小写字母和数字:
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$
这里用了三个正向前瞻来分别检查三种字符是否存在。
const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/;
passwordRegex.test("Abc12345"); // true
passwordRegex.test("abc12345"); // false(缺少大写字母)
正则表达式调试技巧
正则表达式写起来容易出错,掌握调试技巧能帮你少走弯路。
在线测试工具
写正则时,一定要配合在线测试工具实时验证:
- DevToolkit Pro 正则表达式测试器:实时匹配、语法高亮、匹配信息展示
- Regex101:详细的正则解释器
- RegExr:交互式正则学习工具
常见错误与陷阱
1. 忘记转义元字符
想匹配点号却写成了 .,结果匹配了任意字符。记得用 \. 匹配字面量点号。
2. 贪婪匹配导致过度匹配
默认情况下,* 和 + 是贪婪的,会尽可能多地匹配字符:
<.*>
用这个模式匹配 <div>Hello</div>,会匹配整个字符串而不是第一个标签。解决方法是加 ? 变成非贪婪:
<.*?>
3. 字符类中的元字符
在方括号 [ ] 内,大多数元字符会失去特殊含义。比如 [.] 匹配的就是字面量点号,而不是任意字符。
4. ^ 和 $ 的误用
^ 和 $ 默认匹配整个字符串的开头和结尾。如果想匹配每行的开头结尾,需要加上 m 修饰符。
性能优化(贪婪 vs 非贪婪)
虽然非贪婪匹配(*?、+?)很方便,但在某些场景下性能较差。对于长文本,尽量使用更精确的模式代替非贪婪:
# 性能较差
/<[^>]+>/
# 性能更好
/<[^>]+>/
另外,避免过度使用回溯(backtracking),尤其是嵌套量词的情况,可能导致灾难性回溯(catastrophic backtracking)。
使用 DevToolkit Pro 在线正则表达式测试器
写正则最头疼的就是不断试错。使用 DevToolkit Pro 的在线正则表达式测试器,你可以边写边看匹配结果,大大提升效率。
工具介绍
DevToolkit Pro 正则表达式测试器是一个功能强大的在线工具,支持:
- 实时匹配:输入正则和测试文本,立即看到匹配结果
- 语法高亮:匹配到的内容高亮显示,一目了然
- 捕获组查看:每个捕获组的内容单独展示
- 匹配信息:显示匹配数量、匹配位置等详细信息
- 代码生成:一键生成 JavaScript、Python 等语言的代码
实时匹配
在左侧输入你的正则表达式和测试文本,右侧会实时显示:
- 高亮标记所有匹配项
- 列出每个匹配的详细信息
- 展示捕获组内容
无需刷新页面,输入即所得。
flags 切换
工具顶部提供了常用修饰符的快捷开关:
- g:全局匹配
- i:忽略大小写
- m:多行模式
- s:dotAll 模式
- u:Unicode 模式
点击即可切换,实时查看效果,不用手动修改正则表达式。
工具优势
- 纯前端运行:你的正则和测试文本不会上传到服务器,保护隐私
- 零延迟响应:本地计算,匹配速度极快
- 语法参考:内置常用正则语法速查表,边写边查
- 代码导出:一键复制可用的代码片段到你的项目中
- 完全免费:所有功能免费使用,无次数限制
最佳实践
1. 从简单开始,逐步构建
不要试图一次性写出完美的正则。先写最简单的版本,然后逐步添加约束和边界条件。
2. 保持正则简洁可读
过于复杂的正则表达式是维护噩梦。如果一个正则超过 20 个字符,考虑拆分成多个步骤,或者加上注释。
一些语言支持正则注释,比如 JavaScript 的 x 修饰符(需转义空格),或者用字符串拼接:
const regex = new RegExp(
"^" +
"(?=.*[a-z])" + // 至少一个小写字母
"(?=.*[A-Z])" + // 至少一个大写字母
"(?=.*\\d)" + // 至少一个数字
".{8,}" +
"$"
);
3. 优先使用内置方法
很多常见需求(邮箱验证、URL 解析)语言或框架已经提供了内置方法。优先使用经过充分测试的标准库,而不是自己写正则。
4. 充分测试边界情况
写好正则后,一定要测试各种边界情况:
- 空字符串
- 刚好符合长度的输入
- 超出长度的输入
- 特殊字符
- 空匹配的情况
5. 考虑可读性和可维护性
能工作的正则 ≠ 好的正则。优先选择更易读、更易维护的写法,哪怕稍微长一点。
FAQ
正则表达式和通配符有什么区别?
通配符(如 *、?)通常只用于简单的文件名匹配,功能非常有限;而正则表达式是一套完整的模式匹配语言,功能强大得多,可以描述非常复杂的模式。
所有编程语言的正则表达式都一样吗?
基本语法(字符类、量词、锚点等)大致相同,但高级特性(如环视、命名捕获组)的支持程度和具体语法可能有差异。JavaScript、Python、PCRE 是比较常见的流派,使用时注意查阅对应语言的文档。
正则表达式能匹配 HTML 吗?
简单的 HTML 提取可以用正则,但对于复杂的、嵌套的 HTML 结构,正则表达式无法正确处理(因为 HTML 不是正则语言)。正确的做法是使用 HTML 解析器(如浏览器的 DOM API、Python 的 BeautifulSoup 等)。
什么是灾难性回溯?
灾难性回溯(catastrophic backtracking)是指正则表达式在某些输入下需要尝试指数级的匹配路径,导致程序卡死。通常由嵌套的量词(如 (a+)+)引起。避免方法是:尽量减少回溯的可能性,使用更精确的字符类,或者使用原子组(atomic groups)等高级特性。
在线正则测试工具安全吗?
取决于具体工具。很多在线工具会把你的数据发送到服务器处理。如果测试的是敏感数据(如用户隐私、生产环境日志),建议使用纯前端运行的工具。DevToolkit Pro 正则表达式测试器 完全在浏览器本地运行,数据不会上传,可以放心使用。
本文由 DevToolkit Pro 提供。更多开发者工具请访问 首页。
relatedTools
相关文章
最佳在线 JWT 解码工具推荐(2026)
对比主流在线 JWT 解码工具,从签名校验、隐私保护、功能完整度等维度评测。DevToolkit Pro 凭借本地解码和 HS256 签名校验脱颖而出。
最佳在线 Base64 编解码工具推荐(2026)
对比主流在线 Base64 编解码工具,从 Unicode 支持、隐私保护、使用便捷性等维度评测。DevToolkit Pro 凭借本地运行和 Unicode 安全编码成为首选。
在线 Base64 转图片工具:将编码字符串还原为图片文件
学习如何将 Base64 编码字符串还原为图片文件。了解 Base64 解码原理、常见的 Base64 图片格式,以及在 Web 开发中的实际应用场景。