正则表达式是一种强大的文本模式匹配工具,它使用一种特殊的语法来描述要搜索或操作的字符串模式。在 Java 中,我们可以使用 java.util.regex
包提供的类来处理正则表达式。
:::color3
正则表达式不止 Java 语言提供了相应的功能,很多其他语言都提供了对其的支撑,比如:Python、Javascript
:::
正则表达式
简单来说,正则表达式就是一个由特殊字符(称为元字符)和普通字符组成的字符串,用来定义一个搜索模式。这个模式可以用来匹配、查找、替换符合特定规则的文本。
例如,模式 \d+
可以匹配一个或多个数字,模式 [a-z]+
可以匹配一个或多个小写字母。
常用的元字符:
比如,这是一个匹配大多数邮箱地址的正则表达式:
^[\w\-\.]+@([\w\-]+\.)+[\w\-]{2,4}$
^
- 匹配输入的 开始位置。
[\w\-\.]+
- 匹配邮箱的 用户名部分(@ 前面)。
[\w\-\.]
表示可以是以下任意一个字符:\w
:等价于[a-zA-Z0-9_]
(字母、数字或下划线)\-
:减号(-
)\.
:点号(.
)
+
表示上面的字符可以重复出现 1 次或多次。
@
- 邮箱地址中的 @ 符号,用作用户名和域名的分隔。
([\w\-]+\.)+
- 匹配域名部分中前面的部分(例如:
mail.google.
)。 [\w\-]+
:一个或多个字母、数字、下划线或减号。\.
:一个点号。(...) +
:这个结构可以出现一次或多次,表示可以匹配像abc.
、mail.google.
等。
[\w\-]{2,4}
- 匹配最后的顶级域名(如
com
、net
、org
)。 - 范围
{2,4}
表示:2 到 4 个字符之间。 - 允许的字符:字母、数字、下划线、减号。
$
- 匹配输入的 结束位置。
可以在这个网站方便的看到正则表达式的匹配情况:
https://www.mklab.cn/utils/regex
Java 中使用正则表达式
Java 中使用正则表达式的步骤
- 创建
**Pattern**
对象: 使用Pattern.compile(String regex)
编译正则表达式。 - 创建
**Matcher**
对象: 使用pattern.matcher(CharSequence input)
将Pattern
对象应用于输入字符串。 - 进行匹配操作: 使用
Matcher
对象的方法进行查找、匹配和替换等操作。
比如,我们使用上面的邮箱的正则表达式判断字符串是不是一个邮箱地址:
Pattern pattern = Pattern.compile("[\\w\\-\\.]+@([\\w\\-]+\\.)+[\\w\\-]{2,4}");
Matcher matcher1 = pattern.matcher("111111111@qq.com");
System.out.println(matcher1.matches()); // true
Matcher matcher2 = pattern.matcher("123ab");
System.out.println(matcher2.matches()); // false
:::color3
在 Java 字符串中,反斜杠 \
是一个特殊字符,用于转义。因此,在正则表达式中要表示字面意义的反斜杠,需要使用双反斜杠 \\
。例如,要匹配一个点号 .
,正则表达式应该是 \.
,但在 Java 字符串中需要写成 "\\."
。
:::
Matcher
类的常用方法:
方法名 | 作用 |
---|---|
matches() | 尝试将整个输入序列与该模式匹配。只有当整个输入序列完全匹配模式时才返回 true |
find() | 尝试查找与该模式匹配的输入序列的下一个子序列。如果找到匹配项,则返回 true 。可以多次调用 find() 来查找所有匹配项 |
group() | 返回由上一次匹配操作所匹配的子序列。如果匹配成功,group(0) 返回整个匹配的子串。如果正则表达式中包含分组(用括号 () 包围),可以使用 group(n) 来获取第 n 个分组匹配的子串(索引从 1 开始) |
start() | 返回上一次匹配的起始索引 |
end() | 返回上一次匹配的结束索引(不包含) |
replaceAll(String replacement) | 将输入序列中所有匹配该模式的子序列替换为指定的 replacement 字符串。返回一个新的字符串 |
replaceFirst(String replacement) | 将输入序列中第一个匹配该模式的子序列替换为指定的 replacement 字符串。返回一个新的字符串 |
下面是一个使用正则表达式从字符串中统计 Hello 出现次数的例子,每次还打印了找到的 Hello 在字符串中的开始下标(包含)和结束下标(不包含):
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches {
public static void main( String[] args ){
final String REGEX = "\\bHello\\b";
final String INPUT = "Hello world,Hello Tomcat,Hello Java";
Pattern p = Pattern.compile(REGEX);
Matcher m = p.matcher(INPUT); // 获取 matcher 对象
int count = 0;
while (m.find()) {
count++;
System.out.println("Match number " + count);
System.out.println("start(): " + m.start());
System.out.println("end(): " + m.end());
}
}
}
String
类提供了一些方便的方法,入参可以使用正则表达式:
方法名 | 作用 |
---|---|
matches(String regex) | 判断字符串是否完全匹配给定的正则表达式 |
split(String regex) | 根据给定的正则表达式将字符串分割成字符串数组 |
replaceAll(String regex, String replacement) | 将字符串中所有匹配给定的正则表达式的子字符串替换为指定的 replacement 字符串 |
replaceFirst(String regex, String replacement) | 将字符串中第一个匹配给定的正则表达式的子字符串替换为指定的 replacement 字符串 |
下面是使用 String 类的 replaceAll 方法将所有的数字替换为 * 的例子:
String text = "Hello 123 World 456";
String result = text.replaceAll("\\d+", "***"); // Hello *** World ***