文章目录
- [443. Java 正则表达式 - 分组、字符类与量词的结合 & 三种量词模式](#443. Java 正则表达式 - 分组、字符类与量词的结合 & 三种量词模式)
-
- [1. Capturing Groups + Quantifiers 🧩](#1. Capturing Groups + Quantifiers 🧩)
-
- [示例对比 🧪](#示例对比 🧪)
- [2. Character Classes + Quantifiers 🎲](#2. Character Classes + Quantifiers 🎲)
-
- [示例对比 🧪](#示例对比 🧪)
- [3. 三种量词模式的区别 🥊](#3. 三种量词模式的区别 🥊)
-
- 示例:输入串
-
- [3.1 Greedy(贪婪)](#3.1 Greedy(贪婪))
- [3.2 Reluctant(勉强)](#3.2 Reluctant(勉强))
- [3.3 Possessive(独占)](#3.3 Possessive(独占))
- [4. 使用建议 💡](#4. 使用建议 💡)
- [5. 课堂练习 🎤](#5. 课堂练习 🎤)
443. Java 正则表达式 - 分组、字符类与量词的结合 & 三种量词模式
大家好 🚀,在上节我们讲了量词 ? * + {n,m},今天我们要升级一下:
👉 看看量词如何和 分组 (Capturing Groups) 、字符类 (Character Classes) 搭配使用,
以及 贪婪 (Greedy) 、勉强 (Reluctant) 、独占 (Possessive) 三种量词模式的区别。
1. Capturing Groups + Quantifiers 🧩
一个量词默认只能修饰 前面的一个字符 。
比如:
java
abc+
含义是:
- 一个
a,接着一个b,最后一个或多个c。
❌ 注意:它不是 "abc 一组,重复多次"。
如果我们希望量词作用于 整个单词/片段,必须加括号:
java
(abc)+
意思就是:整个 "abc" 作为一个整体,出现 1 次或多次。
示例对比 🧪
例1:
java
(dog){3}
输入:dogdogdogdogdogdog
- 匹配到
"dogdogdog"(前 3 次 dog) - 继续往后,又匹配到
"dogdogdog"(第 4~6 次 dog)
✅ 量词 {3} 作用于整个组 (dog)。
例2:
java
dog{3}
输入:dogdogdogdogdogdog
- ❌ 没有任何匹配
因为这里{3}只修饰"g",意思是:
do+"g"重复 3 次 → 期望匹配"doggg"。
👉 课堂提问 :
如果我写 (ab){2},能匹配 "abab" 吗?(✅ 是的)
如果我写 ab{2},能匹配 "abb" 吗?(✅ 是的)
2. Character Classes + Quantifiers 🎲
量词同样可以修饰 字符类:
java
[abc]{3}
含义是:从 a、b、c 中任选一个字符,重复 3 次。
示例对比 🧪
例1:
java
[abc]{3}
输入:abccabaaaccbbbc
匹配结果:
"abc""cab""aaa""ccb""bbc"
例2:
java
abc{3}
输入:abccabaaaccbbbc
- ❌ 无匹配
因为这里{3}只修饰"c",意思是:ab+"c"连续 3 次 →"abccc"。
👉 课堂总结
(abc)+→ 整个"abc"重复[abc]+→"a"或"b"或"c",随机重复abc+→ 只有"c"重复
3. 三种量词模式的区别 🥊
我们之前用过的量词,其实分三种模式:
- Greedy 贪婪(默认)
- Reluctant 勉强 (加
?) - Possessive 独占 (加
+)
示例:输入串
java
xfooxxxxxxfoo
3.1 Greedy(贪婪)
java
.*foo
结果:
- 匹配
"xfooxxxxxxfoo"(整个字符串)
解释:
.* 先吃掉整串 → 发现 "foo" 没地方了 → 回退,直到找到最后一个 "foo"。
👉 贪婪模式 = 先吃光,再回吐。
3.2 Reluctant(勉强)
java
.*?foo
结果:
- 第一次匹配
"xfoo"(0~4) - 第二次匹配
"xxxxxxfoo"(4~13)
解释:
.*? 先什么都不吃 → 发现 "foo" 没匹配 → 慢慢吃 → 直到 "foo" 出现。
👉 勉强模式 = 先饿着,能不吃就不吃。
3.3 Possessive(独占)
java
.*+foo
结果:
- ❌ 没有匹配
解释:
.*+ 一口吃光,不吐 → "foo" 已经没地方匹配了。
👉 独占模式 = 霸占到底,绝不回吐。
4. 使用建议 💡
-
Greedy:默认选择,常见场景
-
Reluctant :当需要 最短匹配 时用,比如提取 HTML 标签内容
java<.*?> // 最小化匹配 <p> ... </p> -
Possessive:性能优化用,避免回溯浪费时间(比如匹配超长字符串时)
5. 课堂练习 🎤
- 写一个正则,匹配
"cat"或"dog",重复 2 次。
👉 提示:(cat|dog){2} - 用勉强量词,提取字符串
<div>hello</div>中的"hello"。
👉 提示:<.*?>(.*?)<.*?> - 输入:
aaaaab,正则a++b能匹配吗?为什么?
👉 ❌ 不行,因为a++吃掉所有a,不回吐,后面就没b可匹配。