Java 中通过正则表达式可以实现对字符串的有效匹配和处理。本篇文章将详细介绍 Java 中的正则表达式,包括基本概念、语法规则、常用方法等。
一、基本概念
- 正则表达式是什么?
正则表达式(Regular Expression),又称正规表示法,常简称为正则表达式、正则式或规则(Reading),其实是一种字符串匹配的工具,它可以用来描述字符序列的模式。
- 正则表达式的作用
在 Java 中,正则表达式主要用于以下两个方面:
- 文本内容匹配:根据规则匹配指定的字符串。
- 文本内容替换:根据规则将指定字符串中符合条件的部分替换为新的内容。
- 正则表达式的组成
正则表达式由两种基本字符类型组成:
- 原始字符(Literal Character):包含在正则表达式中的普通字符,例如 a、1、$ 等。
- 元字符(Metacharacter):用于描述原始字符的特殊字符,例如 ^、*、? 等。
二、语法规则
- 原子表达式
原子指单个的、不可再分的匹配单元,原子表达式就是由原子组成的正则表达式。常见的原子有:
- 普通字符:包括字母、数字、汉字和一些符号等。
- 转义字符:用来表示正则表达式中的特殊字符,例如 \n 表示换行符。
- 字符类:匹配一组字符中的任意一个字符,用 [] 表示,例如 [abc] 匹配 a、b 或 c 中的任意一个字符。
- 按位字符:与字符类类似,但是可以匹配多个字符,用 [^abc] 表示,表示除了 a、b 和 c 以外的其他字符。
- 元字符:描述原子的性质和它在正则表达式中的作用。
- 元字符
元字符是正则表达式中最为重要和常用的部分,用于匹配单个字符或一组字符。其中常见的元字符如下:
2.1 基本元字符
对应单个字符。
- .:匹配任意一个字符,除了换行符 \n。
- \d:匹配一个数字,等价于 [0-9]。
- \D:匹配一个非数字,等价于 [^0-9]。
- \w:匹配一个单词字符,即字母、数字或下划线,等价于 [a-zA-Z_0-9]。
- \W:匹配一个非单词字符,等价于 [^a-zA-Z_0-9]。
- \s:匹配一个空白字符,包括空格、制表符、换行符等。
- \S:匹配一个非空白字符。
2.2 量词元字符
用于描述字符的数量。
- *:匹配前面的字符出现 0 次或多次。
- +:匹配前面的字符至少出现一次。
- ?:匹配前面的字符出现 0 次或 1 次。
- {n}:匹配前面的字符恰好出现 n 次,其中 n 为一个非负整数。
- {n,}:匹配前面的字符至少出现 n 次。
- {n,m}:匹配前面的字符出现 n 到 m 次。
注意:使用 * 和 + 时,表达式会尽可能地去匹配所有符合条件的字符串。因此,可能会导致效率低下和执行时间过长的问题。如果确定匹配的字符串不会太长,可以使用贪婪模式(Greedy)来提高正则表达式的性能。例如,a.b 会匹配从 a 开始到 b 结束之间的所有内容,包括中间的换行符等;而 a.?b 只会匹配第一个 a 和第一个 b 之间的部分。
2.3 分组元字符
用于将表达式中若干个子项组成一个整体。常用的分组元字符有:
- ():将其中的内容作为一个整体,例如 (ab)+ 表示 ab 出现一次或多次。
- (?😃:只匹配其中的内容,不保留在分组中,例如 (?:ab)+ 表示匹配 ab 出现一次或多次,但是只保留 ab 这个字符串。
2.4 限定符
用于限制某个元字符在正则表达式中出现的次数。常见的限定符有:
- ^:表示匹配输入字符串的开始位置,可以与 $ 一起使用来表示精确匹配。
- $:表示匹配输入字符串的结束位置,可以与 ^ 一起使用来表示精确匹配。
- \b:表示单词边界,例如 \bhello\b 匹配整个单词 hello,而不会匹配到包含该单词的其他单词。
- \B:表示非单词边界,例如 \Bhello\B 匹配包含该单词的其他单词,而不会匹配整个单词 hello。
三、常用方法
Java 中常用的正则表达式方法有 Matcher 和 Pattern 两个类提供,其中 Matcher 类用于对字符串进行匹配和处理,而 Pattern 类则提供了一些常见的正则表达式。
- Matcher 类
Matcher 类是一个抽象类,可以通过调用 Pattern 类的 matcher() 方法来获取 Matcher 对象。
常用方法如下:
- matches():尝试将整个字符序列与正则表达式进行匹配,返回 true 或 false。
- find():在字符串中查找下一个匹配的子串,找到返回 true,没找到返回 false。
- group():返回匹配成功的子串。
- start():返回匹配成功的子串的起始坐标。
- end():返回匹配成功的子串的结束坐标。
- replaceAll():将匹配成功的子串替换为新的字符串。
代码示例:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MatcherDemo {
public static void main(String[] args) {
String str = "This is a test string";
// 创建 Pattern 对象
Pattern pattern = Pattern.compile("\\w+");
// 创建 Matcher 对象
Matcher matcher = pattern.matcher(str);
int count = 0;
while (matcher.find()) {
System.out.println("Match " + (++count) + ": " + matcher.group());
System.out.println("Starting index: " + matcher.start());
System.out.println("Ending index: " + matcher.end());
}
}
}
上面的代码使用 Pattern 类和 Matcher 类来对字符串进行匹配,输出结果如下:
Match 1: This
Starting index: 0
Ending index: 4
Match 2: is
Starting index: 5
Ending index: 7
Match 3: a
Starting index: 8
Ending index: 8
Match 4: test
Starting index: 10
Ending index: 13
Match 5: string
Starting index: 15
Ending index: 20
- Pattern 类
Pattern 类提供了一些常见的正则表达式。
常用方法如下:
- compile():将正则表达式编译为匹配器。
- matcher():返回由Pattern.compile() 方法编译的 Matcher 对象。
- matches():尝试将整个字符序列与正则表达式进行匹配,返回 true 或 false。
- split():根据正则表达式匹配的位置分割字符串。
- replaceAll():将匹配成功的子串替换为新的字符串。
代码示例:
import java.util.Arrays;
import java.util.regex.Pattern;
public class PatternDemo {
public static void main(String[] args) {
String str = "1,2;3,4,5";
// 使用逗号或分号分割字符串
Pattern pattern = Pattern.compile("[,;]");
String[] parts = pattern.split(str);
System.out.println(Arrays.toString(parts));
// 将数字替换为 X
String result = pattern.matcher(str).replaceAll("X");
System.out.println(result);
}
}
上面的代码使用 Pattern 类的 split() 和 replaceAll() 方法来对字符串进行操作,输出结果如下:
[1, 2, 3, 4, 5]
X X X X X
四、总结
本文介绍了 Java 中的正则表达式,包括基本概念、语法规则和常用方法。在使用正则表达式时,应该根据需要选择合适的元字符和限定符,并注意性能问题。同时,建议使用可读性强且易于维护的规则,以提高代码的可读性和可维护性。