Java 正则表达式完全指南:掌握 java.util.regex 模式匹配
Java 通过 java.util.regex 包提供强大的正则表达式支持,其语法与 Perl 高度相似,学习曲线平缓。正则表达式是一种特殊的字符序列,用于匹配、查找或操作符合特定模式的字符串,广泛应用于文本搜索、数据验证、内容替换等场景。
核心类详解
java.util.regex 包主要包含三个核心类:
- Pattern 类:正则表达式的编译表示。无公共构造器,需调用静态
compile()方法创建实例,该方法接受正则表达式字符串作为参数。 - Matcher 类:执行匹配操作的引擎。同样无公共构造器,通过
Pattern.matcher()方法获取实例,用于对输入字符串进行匹配、查找、替换等操作。 - PatternSyntaxException:非受检异常,表示正则表达式语法错误,提供错误描述、错误索引、错误模式等诊断信息。
捕获组
捕获组将多个字符作为一个整体处理,通过圆括号 () 定义。例如 (dog) 创建一个包含 "d"、"o"、"g" 的组。组按左括号从左到右编号,如 ((A)(B(C))) 包含四个组:((A)(B(C)))、(A)、(B(C))、(C)。
调用 Matcher.groupCount() 可获取捕获组数量(不含组 0)。组 0 始终代表整个表达式匹配的内容。
示例:提取数字字符串
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches {
public static void main(String[] args) {
String line = "This order was placed for QT3000! OK?";
String pattern = "(.*)(\\d+)(.*)";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(line);
if (m.find()) {
System.out.println("完整匹配: " + m.group(0));
System.out.println("第1组: " + m.group(1));
System.out.println("第2组: " + m.group(2));
} else {
System.out.println("未匹配");
}
}
}
输出:
完整匹配: This order was placed for QT3000! OK?
第1组: This order was placed for QT300
第2组: 0
正则表达式语法速查表
| 子表达式 | 匹配内容 |
|---|---|
^ | 行首 |
$ | 行尾 |
. | 除换行符外的任意单字符(m 选项可匹配换行) |
[...] | 括号内任意单字符 |
[^...] | 不在括号内的任意单字符 |
\A | 字符串开头 |
\z | 字符串结尾 |
\Z | 字符串结尾(允许末尾换行符) |
re* | 前面表达式 0 次或多次 |
re+ | 前面表达式 1 次或多次 |
re? | 前面表达式 0 次或 1 次 |
re{n} | 前面表达式恰好 n 次 |
re{n,} | 前面表达式至少 n 次 |
re{n,m} | 前面表达式 n 到 m 次 |
a|b | a 或 b |
(re) | 分组并记忆匹配文本 |
(?:re) | 分组但不记忆(非捕获组) |
(?>re) | 独立模式,无回溯 |
\w | 单词字符 [a-zA-Z0-9_] |
\W | 非单词字符 |
\s | 空白字符 [\t\n\r\f] |
\S | 非空白字符 |
\d | 数字 [0-9] |
\D | 非数字 |
\b | 单词边界(括号外)/ 退格符(括号内) |
\B | 非单词边界 |
\Q...\E | 引用字面量,禁用元字符特殊含义 |
Matcher 核心方法
索引方法
| 方法 | 说明 |
|---|---|
start() | 返回上一次匹配的起始索引 |
start(int group) | 返回指定组的起始索引 |
end() | 返回上一次匹配末尾字符的下一个位置 |
end(int group) | 返回指定组末尾字符的下一个位置 |
匹配查找方法
| 方法 | 说明 |
|---|---|
lookingAt() | 从区域开头尝试匹配模式(不要求完全匹配) |
find() | 查找下一个匹配的子序列 |
find(int start) | 从指定索引开始查找下一个匹配 |
matches() | 尝试将整个区域与模式匹配(完全匹配) |
替换方法
| 方法 | 说明 |
|---|---|
appendReplacement(StringBuffer sb, String replacement) | 非终结追加替换步骤 |
appendTail(StringBuffer sb) | 终结追加替换步骤 |
replaceAll(String replacement) | 替换所有匹配的子序列 |
replaceFirst(String replacement) | 替换第一个匹配的子序列 |
quoteReplacement(String s) | 返回字面量替换字符串,用于 appendReplacement |
实战示例:统计单词出现次数
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches {
private static final String REGEX = "\\bcat\\b";
private static final String INPUT = "cat cat cat cattie cat";
public static void main(String[] args) {
Pattern p = Pattern.compile(REGEX);
Matcher m = p.matcher(INPUT);
int count = 0;
while (m.find()) {
count++;
System.out.println("匹配 #" + count);
System.out.println("起始: " + m.start());
System.out.println("结束: " + m.end());
}
}
}
输出显示仅匹配独立单词 "cat"(利用 \b 单词边界),"cattie" 不会被匹配。
matches() 与 lookingAt() 对比
String REGEX = "foo";
String INPUT = "fooooooooooooooooo";
Pattern pattern = Pattern.compile(REGEX);
Matcher matcher = pattern.matcher(INPUT);
System.out.println("lookingAt(): " + matcher.lookingAt()); // true
System.out.println("matches(): " + matcher.matches()); // false
lookingAt() 只检查开头是否匹配,matches() 要求整个字符串完全匹配。
replaceFirst 与 replaceAll 示例
String REGEX = "dog";
String INPUT = "The dog says meow. All dogs say meow.";
String REPLACE = "cat";
Pattern p = Pattern.compile(REGEX);
Matcher m = p.matcher(INPUT);
INPUT = m.replaceAll(REPLACE);
System.out.println(INPUT);
// 输出: The cat says meow. All cats say meow.
appendReplacement 与 appendTail 示例
String REGEX = "a*b";
String INPUT = "aabfooaabfooabfoob";
String REPLACE = "-";
Pattern p = Pattern.compile(REGEX);
Matcher m = p.matcher(INPUT);
StringBuffer sb = new StringBuffer();
while (m.find()) {
m.appendReplacement(sb, REPLACE);
}
m.appendTail(sb);
System.out.println(sb.toString());
// 输出: -foo-foo-foo-
PatternSyntaxException 诊断方法
| 方法 | 说明 |
|---|---|
getDescription() | 获取错误描述 |
getIndex() | 获取错误索引位置 |
getPattern() | 获取错误的正则表达式模式 |
getMessage() | 获取包含错误详情的多行字符串 |
掌握 Java 正则表达式能极大提升文本处理效率,建议结合实际场景多加练习,熟练运用捕获组、边界匹配、贪婪/非贪婪量词等高级特性。
java
- C# 表达式、语句与代码块:全面指南与实战示例
- 精通 Java 运算符:类型、语法与实战示例
- 理解 Java 表达式、语句与代码块
- Java 注释:类型、用法与最佳实践
- 精通 Java 增强 for 循环:语法、示例与最佳实践
- 精通 Java 字符串:创建、方法与最佳实践
- 精通 Java 接口:概念、实现与最佳实践
- 精通 Java Try-With-Resources:自动资源管理详解
- Java 注解详解:类型、放置位置与实战示例
- Java 断言实战指南:尽早发现 Bug 与保障代码可靠性
- 掌握 Java Lambda 表达式:从基础到 Stream API 实战
- Java 正则表达式完全指南:掌握 java.util.regex 模式匹配