1、概念
正则表达式(Regular Expression)是一种强大的文本处理工具,可以用来匹配、查找、替换等操作。
引出例子:校验qq号码是否正确 (qq号码不能为空,首个号码不能为0,qq长度 不能<6或 >20)
不使用正则表达式:
java
public static boolean checkQQ(String qq) {
if (qq == null || qq.startsWith("0") || qq.length() < 6 || qq.length() > 20) {
return false;
}
for (int i = 0; i < qq.length(); i++) {
char ch = qq.charAt(i);
if (!(ch >= '0' && ch <= '9')) {
return false;
}
}
return true;
}
使用正则表达式:
java
public static boolean checkQQregular(String qq) {
return qq != null && qq.matches("[1-9]\\d{5,19}");
}
可以发现使用正则表达式代码非常简洁。
String提供了一个匹配正则表达式的方法:
java
//判断字符串是否匹配正则表达式,匹配返回true,不匹配返回false。
public boolean matches(String regex){};

2、普通字符和元字符
普通字符
普通字符是指那些没有特殊含义的字符,它们在正则表达式中代表自己本身。例如:
a:匹配字母a。5:匹配数字5。.:匹配点号.(注意,.作为元字符有特殊的含义,但在某些情况下也可以用作普通符)。
元字符
元字符元字符是具有特殊含义的字符,在正则表达式中通常用来表示某种模式或者控制匹配的行为。以下是常见的元字符及其用途:
-
锚定符
^:匹配字符串的开始位置。$:匹配字符串的结束位置。
-
重复符
*:匹配前面的子表达式零次或多次。+:匹配前面的子表达式一次或多次。?:匹配前面的子表达式零次或一次。{m,n}:匹配前面的子表达式至少 m 次,但不超过 n 次。
-
选择符
|:表示逻辑"或",用于选择多个可能的匹配之一。
-
字符类
[]:定义一个字符集合,其中的任何一个字符都可以匹配。[^]或[!]:定义一个否定的字符集合,即匹配不在集合内的任何字符。
-
预定义字符类
\d:匹配任何数字,等同于[0-9]。\D:匹配任何非数字,等同于[^0-9]。\w:匹配任何字母数字字符,包括下划线,等同于[a-zA-Z0-9_]。\W:匹配任何非字母数字字符,包括非下划线,等同于[^a-zA-Z0-9_]。\s:匹配任何空白字符,包括空格、制表符、换页符等。\S:匹配任何非空白字符。
-
量词限定符
{n}:匹配前面的子表达式恰好 n 次。{n,}:匹配前面的子表达式至少 n 次。{,m}:匹配前面的子表达式最多 m 次。{n,m}:匹配前面的子表达式至少 n 次,但不超过 m 次。
-
特殊符号
\b:匹配一个单词边界,即单词和非单词字符之间的位置。\B:匹配一个非单词边界,即两个单词字符之间或两个非单词字符之间的位置。
-
转义符
\:用于转义上述元字符或特殊字符,使其失去特殊含义,变成普通字符。例如,\.,\+,\\等。
-
分组与引用
():用于定义一个捕获组。\1,\2, ... :引用之前捕获组的内容。
3、案例
案例1:
校验用户输入的电话,邮箱,时间是否合法
校验电话:
手机号码:13812345678
固定电话号码:021-12345678 或 0755123456789
java
public static void checkPhone() {
while (true) {
System.out.println("输入手机号码");
Scanner sc = new Scanner(System.in);
String phoneNumber = sc.nextLine();
if (phoneNumber.matches("(1[3-9]\\d{9})|(0\\d(2,7)-?[1-9]\\d{4,19})")) {
System.out.println("输入正确");
} else {
System.out.println("输入错误");
}
}
}
对上述正则表达式的解释:
-
手机号码部分
1[3-9]\\d{9}:1: 匹配数字1,这是中国手机号码的前缀。[3-9]: 匹配数字 3 到 9 中的一个,这是手机号码第二位的常见值。\\d{9}: 匹配接下来的 9 位数字,其中\d表示任何数字 (0-9)。
-
固定电话号码或地区代码部分
0\\d(2,7)-?[1-9]\\d{4,19}:0: 匹配数字0,这是中国固定电话号码的前缀。\\d: 匹配一个数字。(2,7): 匹配数字 2 或 7。-?: 可选的短横线-,表示该短横线可能出现也可能不出现。[1-9]: 匹配数字 1 到 9 中的一个,这确保了接下来的数字不是以 0 开始。\\d{4,19}: 匹配接下来的 4 到 19 位数字。
校验邮箱:
username@example.co
username123@example.org
java
public static void checkEmail() {
while (true) {
System.out.println("输入邮箱");
Scanner sc = new Scanner(System.in);
String email = sc.nextLine();
if(email.matches("\\w{2,}@\\w{2,20}(\\ .\\w{2,10}){1,2}")){
System.out.println("输入正确");
break;
}else {
System.out.println("输入错误");
}
}
}
对上述正则表达式的解释:
1.\\w{2,}: 匹配至少两个字母数字字符(包括字母、数字和下划线)。
2.@: 匹配 @ 符号,这是电子邮件地址的一部分。
3.\\w{2,20}: 匹配域名部分,至少包含两个字母数字字符,最长不超过 20 个字符。
4.(\\.\\w{2,10}){1,2}: 匹配顶级域名(TLD)或子域的部分,可以有一个或两个这样的部分。
(4.1) \\.\\w{2,10}: 匹配一个点 . 后跟 2 到 10 个字母数字字符。
(4.2) {1,2}: 表示上面的模式可以出现一次或两次。
案例2:
将下述的本文中的电话,邮箱,座机号码,热线都爬取出来。

java
package javaeeDay01.Test;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test3 {
public static void main(String[] args) {
String data = "来学习Java,\n" +
"电话:18512516758,18512508907\n" +
"或者联系邮箱:boniu@itcast.cn,\n" +
"座机电话:01036517895,010-98951256\n" +
"邮箱:bozai@itcast.cn,\n" +
"邮箱2:dlei0009@163.com,\n" +
"热线电话:400-618-9090,400-618-4000,4006184000,4006189090";
//定义爬取规则
String regex = "(1[3-9]\\d{9})|(0\\d(2,7)-?[1-9]\\d{4,19})" +
"|(\\w{2,}@\\w{2,20}(\\.\\w{2,10}){1,2})" +
"|(400-?\\d{3,7}-?\\d{3,7})";
//封装成Pattern对象
Pattern pattern = Pattern.compile(regex);
//通过pattern对象获取查找内容的匹配器对象
Matcher matcher = pattern.matcher(data);
//定义循环爬取信息
while (matcher.find()) {
String str = matcher.group(); //获取找到的内容
System.out.println(str);
}
}
}
正则表达式用于搜索替换、分割内容,需要结合String提供的如下方法完成:
|--------------------------------------------------------|--------------------------------|
| 方法名 | 说明 |
| public String replaceAll(String regex , String newStr) | 按照正则表达式匹配的内容进行替换 |
| public String[] split(String regex): | 按照正则表达式匹配的内容进行分割字符串,反回一个字符串数组。 |
非中文字符替换成”-"
java
//非中文字符替换成"-";
String s1 = "古力娜扎ai8888迪丽热巴999aa5566马尔扎哈fbbfsfs42425卡尔扎巴";
System.out.println(s1.replaceAll("\\w+", "-"));
简化成我喜欢编程
java
//简化成我喜欢编程
String s2 = "我我喜欢编编编编编编编编编编编编编编编编程程";
System.out.println(s2.replaceAll("(.)\\1+", "$1"));

//获取人名
java
String s3 = "古力娜扎ai8888迪丽热巴999aa5566马尔扎哈fbbfsfs42425卡尔扎巴";
String[] names = s3.split("\\w+");
System.out.println(Arrays.toString(names));