一、怎么创建 Matcher
Matcher是 Java 正则表达式里负责执行匹配操作的类。Pattern是“规则”,Matcher是“按规则去匹配字符串的工具”。
Pattern pattern = Pattern.compile("\\d+"); // 1. 编译正则 Matcher matcher = pattern.matcher("a1 b22 c333"); // 2. 对字符串创建 matcher二、核心方法
1. find() —— 找下一个匹配
while (matcher.find()) { System.out.println(matcher.group()); } // 输出:1, 22, 333- 从当前位置往后找,找到返回
true,找不到返回false。 - 可以反复调用,每次找下一个。
- 最常用,用于遍历所有匹配项。
2. group() —— 取当前匹配的内容
matcher.find(); matcher.group(); // 整个匹配的内容 matcher.group(1); // 第 1 个括号分组的内容 matcher.group(2); // 第 2 个括号分组的内容例子:
Pattern p = Pattern.compile("(\\d+)-(\\d+)"); Matcher m = p.matcher("12-34"); m.find(); m.group() // "12-34" m.group(1) // "12" m.group(2) // "34"注意:group()必须在find()或matches()成功之后调用,否则抛异常。
3. matches() —— 整个字符串是否完全匹配
Pattern p = Pattern.compile("\\d+"); p.matcher("123").matches(); // true p.matcher("a123").matches(); // false(有非数字)要求整个字符串都符合正则。
4. lookingAt() —— 从开头匹配,但不要求匹配到结尾
Pattern p = Pattern.compile("\\d+"); p.matcher("123abc").lookingAt(); // true p.matcher("abc123").lookingAt(); // false(开头不是数字)和matches()的区别:
matches():从头到尾全匹配。lookingAt():只要求开头匹配,后面可以有剩余。
5. replaceAll() —— 替换所有匹配
String s = "a1 b22 c333"; s.replaceAll("\\d+", "#"); // "a# b# c#"这是String的方法,但底层用的就是 Matcher。
也可以用 Matcher:
Matcher m = p.matcher(s); String result = m.replaceAll("#");6. replaceFirst() —— 只替换第一个匹配
"a1 b22 c333".replaceFirst("\\d+", "#"); // "a# b22 c333"7. start() 和 end() —— 匹配的起止位置
Pattern p = Pattern.compile("\\d+"); Matcher m = p.matcher("a1 b22"); while (m.find()) { System.out.println(m.group() + " 位置:" + m.start() + "~" + m.end()); } // 1 位置:1~2 // 22 位置:4~6start():本次匹配的起始索引(包含)。end():本次匹配的结束索引(不包含)。
8. reset() —— 重置匹配器
matcher.reset(); // 从头开始,可以重新 find matcher.reset("新字符串"); // 换成新字符串再匹配9. hitEnd() / requireEnd() —— 高级方法
用于判断匹配是否到达字符串末尾,通常框架内部用,业务代码很少直接调。
三、经典搭配:while + find + group
这是最常见的用法:
Pattern p = Pattern.compile("\\d+"); Matcher m = p.matcher("a1 b22 c333"); while (m.find()) { System.out.println(m.group()); } // 输出: // 1 // 22 // 333口诀:
find()往前走,group()取内容,while循环遍历全部。
四、分组:括号的威力
Pattern p = Pattern.compile("(\\w+)@(\\w+)\\.com"); Matcher m = p.matcher("邮箱:alice@example.com"); if (m.find()) { System.out.println(m.group()); // alice@example.com System.out.println(m.group(1)); // alice System.out.println(m.group(2)); // example }括号把匹配内容分成几组,group(n)取第 n 组。
五、常用方法速查表
| 方法 | 作用 |
|---|---|
find() | 往后找下一个匹配,返回 boolean |
group() | 取当前匹配内容(或分组) |
matches() | 整个字符串是否完全匹配 |
lookingAt() | 从开头匹配,不要求到结尾 |
replaceAll(...) | 替换所有匹配 |
replaceFirst(...) | 替换第一个匹配 |
start()/end() | 匹配的起止索引 |
reset() | 重置匹配器 |
六、完整例子
String text = "订单A123,订单B456,订单C789"; Pattern p = Pattern.compile("订单([A-Z])(\\d+)"); Matcher m = p.matcher(text); while (m.find()) { System.out.println("完整匹配:" + m.group()); System.out.println("字母:" + m.group(1)); System.out.println("数字:" + m.group(2)); System.out.println("位置:" + m.start() + "~" + m.end()); System.out.println("---"); }输出:
完整匹配:订单A123 字母:A 数字:123 位置:0~6 --- 完整匹配:订单B456 字母:B 数字:456 位置:7~13 --- ...