文章目录
- [442. Java 正则表达式 - 量词](#442. Java 正则表达式 - 量词)
-
- [1. 量词速查表 📝](#1. 量词速查表 📝)
- [2. 基本示例 🧪](#2. 基本示例 🧪)
-
- [2.1 `?`:零次或一次](#2.1
?:零次或一次) - [2.2 `*`:零次或多次](#2.2
*:零次或多次) - [2.3 `+`:一次或多次](#2.3
+:一次或多次)
- [2.1 `?`:零次或一次](#2.1
- [3. 零长度匹配 Zero-Length Matches ⚠️](#3. 零长度匹配 Zero-Length Matches ⚠️)
- [4. 限定次数的量词 🎯](#4. 限定次数的量词 🎯)
-
- [4.1 恰好 n 次](#4.1 恰好 n 次)
- [4.2 至少 n 次](#4.2 至少 n 次)
- [4.3 n 到 m 次](#4.3 n 到 m 次)
- [5. 贪婪 vs 勉强 vs 独占 🥊](#5. 贪婪 vs 勉强 vs 独占 🥊)
- [6. 互动练习 🎤](#6. 互动练习 🎤)
442. Java 正则表达式 - 量词
在正则里,量词 的作用就是告诉引擎:
👉 前面的元素要匹配多少次?
比如:
a?表示:零次或一次a*表示:零次或多次a+表示:一次或多次
是不是有点像我们在说话时常用的"至少一次""可以没有""三次刚刚好"?
1. 量词速查表 📝
| Greedy (贪婪) | Reluctant (勉强) | Possessive (独占) | 含义 |
|---|---|---|---|
X? |
X?? |
X?+ |
X,出现 0 或 1 次 |
X* |
X*? |
X*+ |
X,出现 0 次或多次 |
X+ |
X+? |
X++ |
X,出现 1 次或多次 |
X{n} |
X{n}? |
X{n}+ |
X,出现 恰好 n 次 |
X{n,} |
X{n,}? |
X{n,}+ |
X,出现 至少 n 次 |
X{n,m} |
X{n,m}? |
X{n,m}+ |
X,出现 n 到 m 次之间 |
⚡ 默认是 贪婪(Greedy)模式:
- 会尽可能多地匹配字符。
Reluctant(勉强模式)和Possessive(独占模式)的区别我们放到最后再深入讲。
2. 基本示例 🧪
2.1 ?:零次或一次
java
a?
- 输入:
""(空串) → 匹配成功(因为 0 次也行) - 输入:
a→ 匹配成功 - 输入:
b→ 匹配到 空串
👉 ? 最常用于 可选字段 。
例如:colou?r 可以匹配 color 和 colour。
2.2 *:零次或多次
java
a*
- 输入:
""→ 匹配成功 - 输入:
aaaa→ 匹配到aaaa - 输入:
b→ 匹配到空串
👉 常见场景:匹配任意长度的空格
java
\s*
2.3 +:一次或多次
java
a+
- 输入:
""→ ❌ 不匹配 - 输入:
a→ 匹配成功 - 输入:
aaaa→ 匹配到aaaa
👉 常见场景:手机号(必须是 11 位数字,不允许空)
java
\d+
3. 零长度匹配 Zero-Length Matches ⚠️
有些时候,正则匹配的结果是 空字符串。比如:
java
a?
- 输入:
a→ 匹配到"a",但在最后索引位置,还会额外匹配一个""(空串)。
这就是所谓的 零长度匹配 。
它可能出现在:
- 输入串为空时
- 字符串开头
- 字符串结尾
- 两个字符之间
👉 小贴士:
"零长度匹配"很好理解:匹配的是 存在与不存在之间的"空隙"。
4. 限定次数的量词 🎯
4.1 恰好 n 次
java
a{3}
"aa"→ ❌ 不匹配"aaa"→ ✅ 匹配成功"aaaa"→ ✅ 匹配前 3 个
4.2 至少 n 次
java
a{3,}
"aaa"→ ✅"aaaaaa"→ ✅"a"→ ❌
👉 场景:匹配至少 8 位的密码:
java
.{8,}
4.3 n 到 m 次
java
a{3,6}
"aaaaaa"→ 匹配 6 个"aaaaaaaaa"→ 匹配 6 个 + 后面的 3 个
👉 场景:手机号(11 位)
java
^\d{11}$
👉 邮编(5 到 6 位数字)
java
^\d{5,6}$
5. 贪婪 vs 勉强 vs 独占 🥊
假设字符串是 "aaaa",正则是 a+?:
- Greedy 贪婪 :
a+→ 会尽可能多吃 → 匹配"aaaa" - Reluctant 勉强 :
a+?→ 会尽可能少吃 → 第一次只匹配"a",再逐步扩展 - Possessive 独占 :
a++→ 会"一口吃完" → 匹配"aaaa",但不会回溯
👉 举例:
java
String regex = "a+?b";
String input = "aaab";
- Greedy:
aaa→ 再尝试匹配 b ✅ - Reluctant:
a→ 再尝试匹配 b,失败 → 再吃一个 →aa,直到匹配到 b - Possessive:
aaa(独占不回吐) → 再匹配 b ❌
6. 互动练习 🎤
- 写一个正则,匹配 3 到 5 位数字的验证码 。
👉 提示:^\d{3,5}$ - 匹配一段文本里,所有连续出现 2 个以上空格的地方 。
👉 提示:\s{2,} - 匹配邮箱前缀,要求 至少 6 位,由字母、数字或下划线组成 。
👉 提示:^\w{6,}@