RegExp ^ 量词(超详细)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观
前言:正则表达式中的“量词”是什么?
正则表达式(RegExp)是编程语言中用于文本匹配的强大工具,而“量词”则是控制匹配模式的关键角色。简单来说,量词决定了某个模式在字符串中需要出现多少次才能满足匹配条件。例如,a*
表示“零个或多个 a”,b+
表示“至少一个 b”。
在本文中,我们将通过生活化的比喻、代码示例和实际场景,深入探讨正则表达式中的量词规则,帮助读者掌握如何精准控制匹配的“节奏”与“边界”。
一、基础量词:从简单规则开始理解
1.1 基础量词的类型与含义
量词分为 贪婪模式 和 惰性模式,常见的基础量词包括:
量词 | 含义 | 示例 |
---|---|---|
? | 出现 0 次或 1 次 | colou?r 匹配 color 或 colour |
* | 出现 0 次或多次 | a*b 匹配 "b", "ab", "aaab" |
+ | 出现 1 次或多次 | a+b 匹配 "ab", "aab" 但不匹配 "b" |
{n} | 出现恰好 n 次 | a{3} 匹配 "aaa" |
{n,} | 至少出现 n 次 | a{2,} 匹配 "aa", "aaa" |
{n,m} | 出现 n 到 m 次 | a{1,3} 匹配 "a", "aa", "aaa" |
比喻:
量词就像交通信号灯中的“等待”与“通过”规则:?
是“可停可走”,*
是“无限次通过”,+
是“至少通过一次”。
1.2 代码示例:基础量词的实际应用
// 匹配 "color" 或 "colour"
const regex = /colou?r/;
console.log(regex.test("color")); // true
console.log(regex.test("colour")); // true
// 匹配至少两个 "a" 后接 "b"
const regex2 = /a{2,}b/;
console.log(regex2.test("aab")); // true
console.log(regex2.test("ab")); // false
二、贪婪与惰性模式:匹配的“贪吃蛇”与“节食者”
2.1 贪婪模式的默认行为
正则表达式默认使用 贪婪模式,即尽可能多地匹配字符。例如:
// 匹配从第一个 "a" 到最后一个 "c" 之间的所有字符
const regex = /a.*c/;
const str = "abcabc";
console.log(str.match(regex)); // ["abcabc"]
此时,.*
会尽可能多地匹配字符,直到遇到最后一个 c
。
2.2 惰性模式的“收缩”策略
通过在量词后添加 ?
,可以切换为惰性模式,即尽可能少地匹配字符。
// 惰性模式:匹配第一个 "a" 到第一个 "c"
const regex = /a.*?c/;
const str = "abcabc";
console.log(str.match(regex)); // ["abc"]
比喻:
贪婪模式像贪吃蛇,吃掉所有能碰到的食物;惰性模式像节食者,只吃一小口就停下。
三、特殊量词:进阶技巧与常见陷阱
3.1 U
标志:Unicode 属性量词(ES2018 新增)
ES2018 引入了 U
标志,允许在量词前使用 Unicode 属性名称:
// 匹配任意数字字符(包括 Unicode 扩展)
const regex = /\p{Number}/gu;
console.log("① ② 3".match(regex)); // ["①", "②", "3"]
3.2 贪婪 vs. 惰性:常见错误场景
// 错误示例:试图匹配第一个 <div> 标签
const regex = /<div>.*<\/div>/;
const html = "<div>content1</div><div>content2</div>";
console.log(html.match(regex)); // 匹配到整个字符串,包含两个 div
// 正确写法:使用惰性模式
const regexFixed = /<div>.*?<\/div>/g;
console.log(html.match(regexFixed)); // ["<div>content1</div>", "<div>content2</div>"]
3.3 量词嵌套:小心“指数爆炸”
避免在量词中嵌套复杂的模式,否则可能导致性能问题:
// 高风险代码:可能引发“指数爆炸”
const regex = /(a+)+/;
console.log(regex.test("aaaaaaaa")); // 可能导致长时间运行
四、实战案例:量词的综合应用
4.1 案例 1:邮箱地址验证
// 匹配基本邮箱格式
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
console.log(emailRegex.test("test@example.com")); // true
4.2 案例 2:提取 JSON 数据中的键
// 匹配键名(如 "name"、"age")
const regex = /"([\w]+)":/g;
const jsonStr = '{"name":"Alice", "age":30}';
const matches = jsonStr.match(regex);
console.log(matches); // ["\"name\"", "\"age\""]
4.3 案例 3:密码强度验证
// 匹配至少 8 位,含数字和大写字母
const passwordRegex = /^(?=.*\d)(?=.*[A-Z]).{8,}$/;
console.log(passwordRegex.test("Pass1234")); // true
五、总结与进阶建议
5.1 核心要点回顾
- 量词是正则表达式中控制匹配次数的核心工具,需结合场景选择贪婪或惰性模式。
- 特殊量词(如 Unicode 属性)和嵌套规则需谨慎使用,避免性能问题。
- 通过实际案例(如邮箱验证、密码规则)可加深对量词的理解。
5.2 推荐资源与进阶方向
- 书籍:《精通正则表达式》(Jeffrey E.F. Friedl 著)
- 工具:在线正则测试工具(如 regex101.com)
- 进阶主题:正向/反向预查(lookahead/lookbehind)、命名捕获组
通过本文的学习,读者应能熟练运用正则表达式中的量词,解决实际开发中的文本匹配问题。掌握量词的“节奏”与“边界”,就像学会了用一把精准的尺子,能在代码世界中游刃有余地切割、筛选和分析数据。