Java 正则表达式完全指南:Pattern、Matcher 实战

深入介绍 Java 正则表达式的使用方法,包括 Pattern、Matcher 类的详细用法和性能优化。

正则表达式 2026-06-02 10 分钟

Java 正则表达式完全指南:Pattern、Matcher 实战

Java 提供了强大的正则表达式支持。本文详细介绍 Pattern 和 Matcher 类的使用方法。

Pattern 类

Pattern 是正则表达式的编译表示。

编译正则

import java.util.regex.Pattern;

// 编译正则表达式
Pattern pattern = Pattern.compile("^1[3-9]\d{9}$");

// 带标志编译
Pattern pattern = Pattern.compile("hello", Pattern.CASE_INSENSITIVE);

常用标志

标志 说明
CASE_INSENSITIVE 忽略大小写
MULTILINE 多行模式
DOTALL . 匹配换行符
UNICODE_CASE Unicode 大小写

预编译优化

// ❌ 每次都编译
for (String str : list) {
    if (str.matches("^1[3-9]\d{9}$")) {
        // ...
    }
}

// ✅ 预编译
Pattern pattern = Pattern.compile("^1[3-9]\d{9}$");
for (String str : list) {
    if (pattern.matcher(str).matches()) {
        // ...
    }
}

Matcher 类

Matcher 是对输入字符串进行匹配操作的引擎。

基本用法

Pattern pattern = Pattern.compile("\d+");
Matcher matcher = pattern.matcher("hello123world456");

// 查找所有匹配
while (matcher.find()) {
    System.out.println(matcher.group()); // 123, 456
}

常用方法

// 完全匹配
boolean matches = matcher.matches();

// 查找下一个匹配
boolean found = matcher.find();

// 获取匹配结果
String group = matcher.group();  // 完整匹配
String group1 = matcher.group(1); // 第一个分组

// 获取位置
int start = matcher.start();
int end = matcher.end();

// 替换
String result = matcher.replaceAll("replacement");

分组捕获

// 命名分组
Pattern pattern = Pattern.compile("(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})");
Matcher matcher = pattern.matcher("2024-01-15");

if (matcher.matches()) {
    String year = matcher.group("year");   // 2024
    String month = matcher.group("month"); // 01
    String day = matcher.group("day");     // 15
}

实战示例

1. 手机号验证

public static boolean isValidPhone(String phone) {
    return Pattern.matches("^1[3-9]\d{9}$", phone);
}

2. 邮箱验证

public static boolean isValidEmail(String email) {
    return Pattern.matches("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$", email);
}

3. 提取数字

public static List<String> extractNumbers(String text) {
    List<String> numbers = new ArrayList<>();
    Matcher matcher = Pattern.compile("\d+").matcher(text);
    while (matcher.find()) {
        numbers.add(matcher.group());
    }
    return numbers;
}

4. 中文验证

public static boolean isChinese(String str) {
    return Pattern.matches("^[\u4e00-\u9fa5]+$", str);
}

5. 身份证验证

public static boolean isValidIdCard(String idCard) {
    return Pattern.matches("^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$", idCard);
}

性能优化

1. 预编译 Pattern

// 将 Pattern 定义为静态常量
private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\d{9}$");

2. 避免回溯爆炸

// ❌ 可能导致回溯爆炸
Pattern.compile("^(a+)+$");

// ✅ 使用原子组
Pattern.compile("^(?>a+)+$");

3. 使用非捕获组

// 捕获组
Pattern.compile("(http|https)://.*");

// 非捕获组(性能更好)
Pattern.compile("(?:http|https)://.*");

常用正则模式

// 手机号
private static final Pattern PHONE = Pattern.compile("^1[3-9]\d{9}$");

// 邮箱
private static final Pattern EMAIL = Pattern.compile("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$");

// 身份证
private static final Pattern ID_CARD = Pattern.compile("^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$");

// URL
private static final Pattern URL = Pattern.compile("https?://[^\s]+");

// IP 地址
private static final Pattern IP = Pattern.compile("^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$");

总结

Java 的正则表达式功能强大且性能优秀。通过预编译 Pattern、合理使用分组和标志,可以高效地处理字符串匹配和提取任务。

📚 相关文章