正则表达式在Java中的使用及常见场景
一、是什么?
正则表达式(Regular Expression)是一种用特定语法描述的字符串匹配模式,用于在文本中搜索、匹配或替换符合规则的字符串。在Java中通过 java.util.regex
包实现,核心类包括:
Pattern
:编译正则表达式Matcher
:执行匹配操作
二、解决什么问题
- 复杂字符串验证:如邮箱、手机号格式校验
- 文本提取:从日志/文本中提取特定数据(如IP地址)
- 批量替换:快速修改文本格式(如日期格式转换)
- 字符串分割:按复杂规则拆分字符串(如多分隔符)
三、核心方法
方法 | 所属类 | 说明 |
---|---|---|
Pattern.compile(String regex) | Pattern | 编译正则表达式 |
matcher(CharSequence input) | Pattern | 创建Matcher对象 |
matches() | Matcher | 全文本匹配 |
find() | Matcher | 查找下一个匹配 |
group() | Matcher | 获取匹配内容 |
replaceAll(String replacement) | String | 全局替换 |
四、应用场景(代码题常见情况)
1. 格式验证
java
// 验证手机号(1开头,11位数字)
String regex = "^1[3-9]\\d{9}$";
System.out.println("13812345678".matches(regex)); // true
2. 文本提取
java
// 提取文本中所有日期(格式:YYYY-MM-DD)
String text = "2023-01-15记录 2024-05-20更新";
Pattern p = Pattern.compile("\\d{4}-\\d{2}-\\d{2}");
Matcher m = p.matcher(text);
while (m.find()) {
System.out.println(m.group()); // 输出两个日期
}
3. 字符串分割
java
// 按多种符号分割
String str = "apple,banana;orange|grape";
String[] fruits = str.split("[,;|]");
// 结果: ["apple", "banana", "orange", "grape"]
4. 替换操作
java
// 隐藏手机号中间4位
String phone = "13812345678";
String masked = phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
// 结果: 138****5678
五、JDK8+新特性
Pattern.asPredicate()
将正则转为Predicate,用于Stream过滤javaList<String> emails = Arrays.asList("a@test.com", "invalid"); Pattern emailPattern = Pattern.compile(".+@.+\\..+"); emails.stream() .filter(emailPattern.asPredicate()) .forEach(System.out::println); // 输出有效邮箱
Matcher.replaceAll(Function)
动态替换匹配内容javaMatcher m = Pattern.compile("\\d+").matcher("a1b23c"); String result = m.replaceAll(match -> String.valueOf(Integer.parseInt(match.group()) * 2)); // 结果: "a2b46c"
六、常用正则模式速查
场景 | 正则表达式 | 说明 |
---|---|---|
邮箱 | \w+@\w+\.\w+ | 基础邮箱校验 |
中文 | [\u4e00-\u9fa5] | 匹配单个汉字 |
IP地址 | `((25[0-5] | 2[0-4]\d |
URL | https?://\S+ | HTTP/HTTPS链接 |
日期 | \d{4}-\d{2}-\d{2} | YYYY-MM-DD格式 |
七、重要注意事项
性能优化:
- 多次使用的正则用
Pattern.compile()
预编译 - 避免回溯爆炸(如避免嵌套量词
(a+)+
)
- 多次使用的正则用
特殊字符转义:
- 元字符
. * + ? ^ $ | \ ( ) [ ] { }
需用\\
转义
(例如匹配点号需写\\.
)
- 元字符
贪婪 vs 懒惰匹配:
- 默认贪婪模式(尽可能多匹配),添加
?
变懒惰(尽可能少)
java"a<b>c</b>d".replaceAll("<.*>", ""); // 贪婪: 空字符串 "a<b>c</b>d".replaceAll("<.*?>", ""); // 懒惰: "acd"
- 默认贪婪模式(尽可能多匹配),添加
分组引用:
- 用
()
捕获分组,$1
$2
引用分组
- 用
八、总结
正则表达式是处理字符串的瑞士军刀,在Java中通过:
- 匹配验证 →
String.matches()
- 提取数据 →
Matcher.find()
+group()
- 文本替换 →
replaceAll()
- 复杂分割 →
split()
代码题高频场景:数据清洗、格式校验、日志解析。掌握常用模式(邮箱、手机号、日期)和JDK8新特性可显著提升编码效率!