Java正则表达式速查表(Regex Java Cheat Sheet)
简介
正则表达式(Regular Expressions,简称Regex)是一种用于描述字符串模式的工具。在Java中,正则表达式被广泛应用于字符串的匹配、查找、替换和分割等操作。这份Java正则表达式速查表将帮助你快速掌握正则表达式在Java中的基础概念、使用方法、常见实践及最佳实践。
目录
- 基础概念
- 使用方法
- 匹配
- 查找
- 替换
- 分割
- 常见实践
- 验证电子邮件地址
- 验证电话号码
- 提取URL
- 最佳实践
- 预编译正则表达式
- 避免复杂度过高的正则表达式
- 使用命名捕获组
- 小结
- 参考资料
基础概念
字符类
[abc]
:匹配方括号内指定的任意一个字符,如[abc]
可以匹配a
、b
或c
。[^abc]
:匹配不在方括号内指定的任意一个字符,即取反。[a-zA-Z]
:匹配任意一个大小写字母。[0-9]
:匹配任意一个数字。
预定义字符类
.
:匹配任意一个字符(除了换行符\n
)。\d
:匹配任意一个数字,等价于[0-9]
。\D
:匹配任意一个非数字字符,等价于[^0-9]
。\s
:匹配任意一个空白字符,包括空格、制表符、换行符等。\S
:匹配任意一个非空白字符。\w
:匹配任意一个单词字符,包括字母、数字和下划线,等价于[a-zA-Z0-9_]
。\W
:匹配任意一个非单词字符,等价于[^a-zA-Z0-9_]
。
数量词
*
:匹配前面的字符零次或多次。例如,a*
可以匹配空字符串、a
、aa
、aaa
等。+
:匹配前面的字符一次或多次。例如,a+
可以匹配a
、aa
、aaa
等,但不能匹配空字符串。?
:匹配前面的字符零次或一次。例如,a?
可以匹配空字符串或a
。{n}
:匹配前面的字符恰好n
次。例如,a{3}
只能匹配aaa
。{n,}
:匹配前面的字符至少n
次。例如,a{3,}
可以匹配aaa
、aaaa
、aaaaa
等。{n,m}
:匹配前面的字符至少n
次,最多m
次。例如,a{3,5}
可以匹配aaa
、aaaa
、aaaaa
。
分组
使用圆括号()
进行分组。例如,(ab)+
表示ab
这个组合出现一次或多次。分组可以用于捕获匹配的内容,也可以用于对一组字符应用数量词。
捕获组
在分组中,从左到右,每一个左括号(
开始的分组为一个捕获组。捕获组可以在后续操作中引用。例如,(a(b)c)
中有两个捕获组,第一个捕获组捕获abc
,第二个捕获组捕获b
。
使用方法
匹配
在Java中,可以使用java.util.regex.Pattern
和java.util.regex.Matcher
类来进行正则表达式的匹配。
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class RegexMatchExample {
public static void main(String[] args) {
String regex = "\\d+"; // 匹配一个或多个数字
String input = "123abc456";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
System.out.println("匹配到的内容: " + matcher.group());
} else {
System.out.println("未找到匹配内容");
}
}
}
查找
使用Matcher
类的find()
方法可以查找所有匹配的子字符串。
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class RegexFindExample {
public static void main(String[] args) {
String regex = "\\d+"; // 匹配一个或多个数字
String input = "123abc456def789";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
System.out.println("找到匹配: " + matcher.group());
}
}
}
替换
使用Matcher
类的replaceAll()
方法可以替换所有匹配的子字符串。
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class RegexReplaceExample {
public static void main(String[] args) {
String regex = "\\d+"; // 匹配一个或多个数字
String input = "123abc456def789";
String replacement = "X";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
String result = matcher.replaceAll(replacement);
System.out.println("替换后的字符串: " + result);
}
}
分割
使用Pattern
类的split()
方法可以根据正则表达式分割字符串。
import java.util.regex.Pattern;
public class RegexSplitExample {
public static void main(String[] args) {
String regex = "\\s+"; // 匹配一个或多个空白字符
String input = "Hello World Java";
Pattern pattern = Pattern.compile(regex);
String[] parts = pattern.split(input);
for (String part : parts) {
System.out.println(part);
}
}
}
常见实践
验证电子邮件地址
import java.util.regex.Pattern;
public class EmailValidator {
private static final String EMAIL_PATTERN =
"^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}$";
private static final Pattern pattern = Pattern.compile(EMAIL_PATTERN);
public static boolean validate(String email) {
return pattern.matcher(email).matches();
}
public static void main(String[] args) {
String email1 = "[email protected]";
String email2 = "invalid-email";
System.out.println(validate(email1)); // true
System.out.println(validate(email2)); // false
}
}
验证电话号码
import java.util.regex.Pattern;
public class PhoneNumberValidator {
private static final String PHONE_NUMBER_PATTERN =
"^\\d{3}-\\d{3}-\\d{4}$";
private static final Pattern pattern = Pattern.compile(PHONE_NUMBER_PATTERN);
public static boolean validate(String phoneNumber) {
return pattern.matcher(phoneNumber).matches();
}
public static void main(String[] args) {
String phone1 = "123-456-7890";
String phone2 = "1234567890";
System.out.println(validate(phone1)); // true
System.out.println(validate(phone2)); // false
}
}
提取URL
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class UrlExtractor {
private static final String URL_PATTERN =
"https?://(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}(?:/[^\\s]*)?";
private static final Pattern pattern = Pattern.compile(URL_PATTERN);
public static void extractUrls(String text) {
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
System.out.println(matcher.group());
}
}
public static void main(String[] args) {
String text = "Visit my website at https://www.example.com and check out https://example.org";
extractUrls(text);
}
}
最佳实践
预编译正则表达式
多次使用同一个正则表达式时,应预编译Pattern
对象,而不是每次都调用Pattern.compile()
。
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class PrecompiledRegexExample {
private static final Pattern pattern = Pattern.compile("\\d+");
public static void main(String[] args) {
String input1 = "123abc";
String input2 = "def456";
Matcher matcher1 = pattern.matcher(input1);
Matcher matcher2 = pattern.matcher(input2);
if (matcher1.find()) {
System.out.println("匹配到的内容: " + matcher1.group());
}
if (matcher2.find()) {
System.out.println("匹配到的内容: " + matcher2.group());
}
}
}
避免复杂度过高的正则表达式
复杂的正则表达式不仅难以理解和维护,而且可能导致性能问题。尽量将复杂的匹配逻辑拆分成多个简单的正则表达式。
使用命名捕获组
在Java 9及以上版本中,可以使用命名捕获组,使代码更易读。
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class NamedGroupExample {
public static void main(String[] args) {
String regex = "(?<firstName>[a-zA-Z]+) (?<lastName>[a-zA-Z]+)";
String input = "John Doe";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
System.out.println("名字: " + matcher.group("firstName"));
System.out.println("姓氏: " + matcher.group("lastName"));
}
}
}
小结
正则表达式在Java中是一个强大的工具,用于字符串的处理。通过掌握基础概念、使用方法、常见实践和最佳实践,你可以更高效地使用正则表达式来解决各种字符串相关的问题。希望这份速查表能帮助你在Java开发中更熟练地运用正则表达式。