js 正则(长文解析)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新开坑项目:《Spring AI 项目实战》 正在持续爆肝中,基于 Spring AI + Spring Boot 3.x + JDK 21..., 点击查看 ;
- 《从零手撸:仿小红书(微服务架构)》 已完结,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
前言
在 JavaScript 开发中,js 正则表达式是处理字符串的“瑞士军刀”。无论是验证用户输入、提取特定模式的数据,还是替换文本内容,正则表达式都能提供高效且灵活的解决方案。对于编程初学者,它可能显得抽象;但对于中级开发者,掌握它能显著提升代码的简洁性和可维护性。本文将从基础语法到实战案例,逐步解析 js 正则的核心知识点,帮助读者建立系统化的理解。
正则表达式基础语法
基本结构与创建方式
正则表达式由两部分构成:模式(pattern)和修饰符(flags)。在 JavaScript 中,可以通过以下两种方式创建:
- 正则字面量:用
/
符号包裹模式,例如/abc/
。 - 构造函数:通过
new RegExp('pattern', 'flags')
动态生成,适合模式需要动态构建的场景。
示例代码:
// 正则字面量
const regex1 = /hello/;
// 构造函数(注意转义字符需要双写)
const regex2 = new RegExp("h[e]llo");
元字符与字符匹配
正则表达式中,某些字符具有特殊含义,称为“元字符”(如 .
*
+
)。例如:
.
匹配任意单个字符(除换行符外);^
表示字符串的开头,例如/^hello/
仅匹配以 "hello" 开头的文本;$
表示字符串的结尾,例如/world$/
仅匹配以 "world" 结尾的文本。
比喻:可以把正则表达式想象成一张“通缉令”,元字符就是通缉令上的关键线索,例如 .
就像“任意身高的人”,^
则是“必须穿红色外套入场”。
常见元字符与字符类
特殊字符的转义
若要匹配元字符本身,需用反斜杠 \
转义。例如:
// 匹配字符 '.'
const regex = /\./;
console.log(regex.test("a.b")); // true
预定义字符类
JavaScript 支持多种字符类,简化常见匹配场景:
| 字符类 | 描述 | 示例模式 |
|-------|--------------------------|------------------------|
| \d
| 匹配任意数字(0-9) | /^\d{4}$/
匹配四位数 |
| \w
| 匹配字母、数字或下划线 | /^\w{6,}$/
基础密码验证 |
| \s
| 匹配空白字符(空格、换行等) | /^\s*$/
判断全空白字符串 |
自定义字符集合
使用方括号 []
定义字符集合,例如:
[abc]
匹配单个字符 a、b 或 c;[^abc]
匹配除 a、b、c 以外的任意单个字符。
案例:验证邮箱域名部分是否为 "com" 或 "cn":
const regex = /\.([c][o][m]|[c][n])$/i;
console.log(regex.test("example.com")); // true
量词与模式重复
基本量词
量词控制前面元素的重复次数:
| 量词 | 含义 | 示例模式 |
|------|--------------------|--------------------|
| *
| 出现 0 次或多次 | /a*/
匹配空字符串或多个 a |
| +
| 出现 1 次或多次 | /a+/
匹配至少一个 a |
| ?
| 出现 0 次或 1 次 | /colou?r/
匹配 "color" 或 "colour" |
贪心与非贪心匹配
默认的量词是“贪心”的,即尽可能多匹配。添加 ?
可变为“非贪心”:
const html = "<div>content</div>";
// 贪心匹配
console.log(/<.*>/.exec(html)); // ["<div>content</div>"]
// 非贪心匹配
console.log(/<.*?>/i.exec(html)); // ["<div>"]
分组与捕获
捕获组
用小括号 ()
定义捕获组,可提取匹配内容:
const url = "https://www.example.com/path";
const regex = /:\/\/(www\.)?(\w+)\.(\w+)/;
const matches = url.match(regex);
console.log(matches[1]); // "www."(如果存在)
console.log(matches[2]); // "example"
反向引用
捕获组的内容可在替换时通过 $n
引用:
const text = "Hello World";
console.log(text.replace(/(\w+) (\w+)/, "$2, $1")); // "World, Hello"
零宽断言与边界匹配
预查(Lookahead)
预查通过 (?=...)
或 (?!...)
检查当前位置是否满足条件,但不消耗字符:
- 正向预查:
/password(?=\d)/
要求 "password" 后跟数字; - 负向预查:
/password(?!admin)/
要求 "password" 后不跟 "admin"。
后顾(Lookbehind)
通过 (?<=...)
或 (?<!...)
检查当前位置前的模式:
// 匹配以 http:// 或 https:// 开头的 URL
const regex = /(?<=^https?://).*$/;
console.log(regex.exec("http://example.com")); // "example.com"
实战案例:常见场景应用
案例 1:邮箱验证
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
console.log(emailRegex.test("user@example.com")); // true
解析:
^[a-zA-Z0-9._%+-]+
匹配用户名部分;@[a-zA-Z0-9.-]+\.
匹配 @ 符号和域名;[a-zA-Z]{2,}$
确保域名后缀至少两位。
案例 2:密码强度检测
const passwordRegex = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}$/;
// 需包含数字、小写字母、大写字母,且长度≥8
案例 3:提取电话号码国家代码
const phone = "+86 13800138000";
const regex = /^\+(\d{1,3})/;
console.log(regex.exec(phone)[1]); // "86"
性能优化与注意事项
避免“灾难性回溯”
复杂量词组合可能导致正则引擎无限循环,例如 /(a+)+/
匹配 "aaaa" 时可能崩溃。应尽量简化模式或使用非捕获组 (?:...)
。
全局匹配与标志位
g
标志开启全局匹配,例如/hello/g
可匹配所有 "hello";i
标志启用大小写不敏感;m
标志支持多行匹配。
结论
js 正则表达式是 JavaScript 开发者的必备工具,其核心在于理解元字符、量词、分组和断言的逻辑关系。通过本文的示例和案例,读者应能掌握从基础语法到复杂场景的应用能力。建议在项目中逐步实践,例如通过验证表单输入、解析日志文件或重构字符串处理代码,进一步巩固技能。记住,正则表达式的设计需平衡简洁性与可读性,避免过度复杂化模式。
提示:在 Chrome 开发者工具的 Console 中输入
/pattern/
,可快速测试正则表达式的行为,这对调试非常有帮助。