Java 正则表达式完全指南
·
Java 正则表达式完全指南
Java通过 java.util.regex 包提供正则表达式支持,主要包含 Pattern 和 Matcher 两个核心类。本指南将详细介绍Java中正则表达式的使用方法和最佳实践。
1. 基础知识
1.1 主要类介绍
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class RegexBasics {
public static void main(String[] args) {
// Pattern 类:编译正则表达式
Pattern pattern = Pattern.compile("\\d+");
// Matcher 类:执行匹配操作
Matcher matcher = pattern.matcher("123");
// String 类的正则方法
"text".matches("\\w+"); // 匹配
"text".replaceAll("\\w+", "*"); // 替换
"text".split("\\s+"); // 分割
}
}
1.2 基本匹配方法
public class RegexMethods {
public static void main(String[] args) {
String text = "Hello, my phone is 123-456-7890";
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher(text);
// 1. 查找第一个匹配
if (matcher.find()) {
System.out.println("First match: " + matcher.group());
}
// 2. 查找所有匹配
matcher.reset(); // 重置匹配器
while (matcher.find()) {
System.out.println("Found: " + matcher.group());
}
// 3. 完全匹配
System.out.println("123".matches("\\d+")); // true
}
}
2. 正则表达式语法
2.1 字符匹配
public class CharacterMatching {
public static void main(String[] args) {
String text = "Java 17 is awesome! Price: $99.99";
// 匹配数字
Pattern digits = Pattern.compile("\\d+");
// 匹配单词
Pattern words = Pattern.compile("\\w+");
// 匹配空白字符
Pattern spaces = Pattern.compile("\\s+");
// 自定义字符类
Pattern vowels = Pattern.compile("[aeiou]");
// 使用Matcher查找
Matcher matcher = digits.matcher(text);
while (matcher.find()) {
System.out.println("Number found: " + matcher.group());
}
}
}
2.2 量词使用
public class Quantifiers {
public static void main(String[] args) {
String text = "Java JavaJava JavaJavaJava";
// * - 零次或多次
Pattern p1 = Pattern.compile("Java*");
// + - 一次或多次
Pattern p2 = Pattern.compile("Java+");
// ? - 零次或一次
Pattern p3 = Pattern.compile("Java?");
// {n} - 精确n次
Pattern p4 = Pattern.compile("(Java){2}");
// {n,m} - n到m次
Pattern p5 = Pattern.compile("(Java){2,3}");
}
}
3. 高级特性
3.1 分组和捕获
public class GroupingExample {
public static void main(String[] args) {
String text = "John Smith, Jane Doe, Bob Johnson";
Pattern pattern = Pattern.compile("(\\w+)\\s(\\w+)");
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
System.out.println("First name: " + matcher.group(1));
System.out.println("Last name: " + matcher.group(2));
}
// 命名捕获组
Pattern namedPattern = Pattern.compile("(?<first>\\w+)\\s(?<last>\\w+)");
Matcher namedMatcher = namedPattern.matcher(text);
while (namedMatcher.find()) {
System.out.println("First name: " + namedMatcher.group("first"));
System.out.println("Last name: " + namedMatcher.group("last"));
}
}
}
3.2 边界匹配
public class BoundaryMatching {
public static void main(String[] args) {
String text = "Hello World\nNew Line";
// ^ - 行的开始
Pattern startLine = Pattern.compile("^Hello");
// $ - 行的结束
Pattern endLine = Pattern.compile("Line$");
// \b - 单词边界
Pattern wordBoundary = Pattern.compile("\\bWorld\\b");
// 多行模式
Pattern multiLine = Pattern.compile("^\\w+", Pattern.MULTILINE);
}
}
4. 实用示例
4.1 数据验证器
public class Validator {
// 编译后的Pattern是线程安全的,可以静态存储
private static final Pattern EMAIL_PATTERN =
Pattern.compile("^[A-Za-z0-9+_.-]+@(.+)$");
private static final Pattern PHONE_PATTERN =
Pattern.compile("^1[3-9]\\d{9}$");
private static final Pattern PASSWORD_PATTERN =
Pattern.compile("^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}$");
public static boolean validateEmail(String email) {
return email != null && EMAIL_PATTERN.matcher(email).matches();
}
public static boolean validatePhone(String phone) {
return phone != null && PHONE_PATTERN.matcher(phone).matches();
}
public static boolean validatePassword(String password) {
return password != null && PASSWORD_PATTERN.matcher(password).matches();
}
}
4.2 文本处理工具
public class TextProcessor {
private static final Pattern URL_PATTERN =
Pattern.compile("https?://(?:[-\\w.]|(?:%[\\da-fA-F]{2}))+[^\\s]*");
private static final Pattern HTML_TAG_PATTERN =
Pattern.compile("<[^>]+>");
// 提取URL
public static List<String> extractUrls(String text) {
List<String> urls = new ArrayList<>();
Matcher matcher = URL_PATTERN.matcher(text);
while (matcher.find()) {
urls.add(matcher.group());
}
return urls;
}
// 清理HTML标签
public static String stripHtmlTags(String html) {
return HTML_TAG_PATTERN.matcher(html).replaceAll("");
}
// 清理多余空白
public static String cleanWhitespace(String text) {
return text.replaceAll("\\s+", " ").trim();
}
}
5. 性能优化
5.1 Pattern复用
public class RegexOptimization {
// 正确方式:复用编译后的Pattern
private static final Pattern NUMBER_PATTERN = Pattern.compile("\\d+");
public static List<String> findNumbers(String text) {
List<String> numbers = new ArrayList<>();
Matcher matcher = NUMBER_PATTERN.matcher(text);
while (matcher.find()) {
numbers.add(matcher.group());
}
return numbers;
}
// 错误方式:重复编译Pattern
public static boolean badExample(String text) {
return text.matches("\\d+"); // 每次调用都会重新编译
}
}
5.2 StringBuilder优化
public class StringBuilderExample {
public static String replaceWithCallback(String input, Pattern pattern,
Function<String, String> callback) {
Matcher matcher = pattern.matcher(input);
StringBuilder result = new StringBuilder();
int lastIndex = 0;
while (matcher.find()) {
result.append(input, lastIndex, matcher.start());
result.append(callback.apply(matcher.group()));
lastIndex = matcher.end();
}
result.append(input, lastIndex, input.length());
return result.toString();
}
}
6. 异常处理
public class RegexExceptionHandling {
public static Pattern compilePattern(String regex) {
try {
return Pattern.compile(regex);
} catch (PatternSyntaxException e) {
System.err.println("Invalid regex pattern: " + e.getMessage());
System.err.println("Pattern: " + e.getPattern());
System.err.println("Index: " + e.getIndex());
return null;
}
}
public static boolean safeMatch(String text, String regex) {
try {
Pattern pattern = Pattern.compile(regex);
return pattern.matcher(text).matches();
} catch (PatternSyntaxException e) {
System.err.println("Regex syntax error: " + e.getMessage());
return false;
} catch (Exception e) {
System.err.println("Unexpected error: " + e.getMessage());
return false;
}
}
}
7. 单元测试
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class ValidatorTest {
@Test
public void testEmailValidation() {
assertTrue(Validator.validateEmail("test@example.com"));
assertTrue(Validator.validateEmail("user@domain.co.uk"));
assertFalse(Validator.validateEmail("invalid.email"));
assertFalse(Validator.validateEmail("@domain.com"));
}
@Test
public void testPhoneValidation() {
assertTrue(Validator.validatePhone("13812345678"));
assertFalse(Validator.validatePhone("12345678"));
assertFalse(Validator.validatePhone("2381234567"));
}
@Test
public void testPasswordValidation() {
assertTrue(Validator.validatePassword("Pass1word@"));
assertFalse(Validator.validatePassword("password"));
assertFalse(Validator.validatePassword("12345678"));
}
}
8. 常见问题和解决方案
8.1 特殊字符处理
public class SpecialCharacterHandling {
public static String escapeSpecialCharacters(String literal) {
return Pattern.quote(literal);
}
public static String createRegexFromLiteral(String literal) {
StringBuilder regex = new StringBuilder();
for (char c : literal.toCharArray()) {
if ("[](){}.*+?^$\\|".indexOf(c) != -1) {
regex.append('\\');
}
regex.append(c);
}
return regex.toString();
}
}
8.2 Unicode支持
public class UnicodeSupport {
public static void main(String[] args) {
// 使用UNICODE_CHARACTER_CLASS标志
Pattern pattern = Pattern.compile("\\p{L}+",
Pattern.UNICODE_CHARACTER_CLASS);
String text = "Hello 你好 こんにちは";
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
System.out.println("Found: " + matcher.group());
}
}
}
总结
Java的正则表达式实现具有以下特点:
- 强大的Pattern和Matcher类
- 完整的Unicode支持
- 线程安全的Pattern对象
- 丰富的API支持
最佳实践:
- 复用编译后的Pattern对象
- 使用命名捕获组提高可读性
- 正确处理特殊字符
- 注意性能优化
- 做好异常处理
- 编写单元测试
注意事项:
- Pattern编译开销较大,应该重用
- 避免在循环中创建Pattern对象
- 使用StringBuilder优化字符串操作
- 考虑Unicode支持需求
记住:在Java中使用正则表达式时,应该平衡效率和可维护性。合理使用Pattern的复用机制,可以显著提高性能。同时,通过良好的代码组织和命名约定,保持代码的可维护性。
更多推荐
所有评论(0)