目录
1. 正则表达式基本介绍
正则表达式(regular expression,简写为regex),Java提供了正则表达式技术,专门用于处理类似文本问题,就是用某种模式去匹配字符串的一个公式。换句话说,正则表达式是对字符串执行模式匹配的技术。
2. 正则表达式语法
2.1 基本介绍
了解正则表达式中各种元字符的功能是灵活运用正则表达式的基础。
 元字符从功能上可以分为:
- 限定符
 - 定位符
 - 字符匹配符
 - 选择匹配符
 - 分组组合和反向引用符
 - 特殊字符
 
2.2 元字符
2.2.1 转义符 \\
说明:在使用正则表达式检索一些特殊字符时,需要用到转义符号。
 提示:Java的正则表达式中,两个斜杠 \\ 代表其他语言的一个 
 注意:几个需要用到转义符的字符有:* + ( ) $ / \ ? [ ] ^ { }
 代码示例:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
//正则表达式_元字符_转义号
public class EX01 {
	public static void main(String[] args) {
		String content = "abc$(abc(123(";  
		//匹配( => \\(
		String regStr = "\\(";    //注意这里的双斜杠转义号
		
		//创建正则表达式对象
		Pattern pattern = Pattern.compile(regStr);
		
		//创建匹配器 matcher,按照 正则表达式的规则 去匹配 content 字符串
		Matcher matcher = pattern.matcher(content);
		
		//matcher.find() 会根据指定的规则,定位满足规则的子字符串
		//group(0) 表示匹配到的子字符串
		while(matcher.find()) {
			System.out.println("找到 " + matcher.group(0));
		}
	}
}
 
运行结果:
找到 (
找到 (
找到 (
 
2.2.2 字符匹配符
| 符号 | 含义 | 示例 | 解释 | 匹配的输入示例 | 
|---|---|---|---|---|
| [ ] | 可接收的字符列表 | [abcd] | a、b、c、d中任意一个字符 | a | 
| [^] | 不接收的字符列表 | [^abc] | 除a、b、c之外的任意一个字符,包括数字与特殊符号 | d | 
| - | 连字符 | A-Z | A至Z中任意一个大写字母(包括A和Z) | A | 
| . | 匹配除 \n 以外的任何字符。 若要匹配 . 本身则需要使用 \\ | a…b | 以a开头,b结尾,中间为两个任意字符的长度为4的字符串 | abcb、a12b、a*#b | 
| \\d | 匹配单个数字字符,相当于[0-9] | \\d\\d\\d | 包含3个数字的字符串 | 123 | 
| \\D | 匹配单个非数字字符,相当于[^0-9] | \\D(\\d)* | 以单个非数字字符开头,后接任意个数数字字符串 | a、A123 | 
| \\w | 匹配单个数字、大小写字母字符,相当于[0-9a-zA-Z] | \\w\\w\\w | 长度为3的数字字母字符串 | 12a、bDc | 
| \\W | 匹配单个非数字、大小写字母字符,相当于[^0-9a-zA-Z] | \\W + \\d{2} | 以至少1个非数字字母字符开头、2个数字字符结尾的字符串 | #12、@#23 | 
代码示例:(此处只示范了[a-z],其余类似,可自行尝试)
import java.util.regex.Matcher;
import java.util.regex.Pattern; 
//正则表达式_元字符_字符匹配符
public class EX02 {
	public static void main(String[] args) {
		String content = "a2cd6"; 
		
		//匹配 a-z 之间任意一个字符
		String regStr = "[a-z]";
		Pattern pattern = Pattern.compile(regStr);
		Matcher matcher = pattern.matcher(content);
		
		while(matcher.find()) {
			System.out.println("找到 " + matcher.group(0));
		}
	}
}
 
运行结果:
找到 a
找到 c
找到 d
 
2.2.3 选择匹配符
| 符号 | 含义 | 示例 | 解释 | 匹配的输入示例 | 
|---|---|---|---|---|
| | | 匹配 “|” 之前或之后的表达式 | ab|cd | ab或者cd | ab、cd | 
2.2.4 限定符
用于指定其前面的字符和组合项连续出现多少次
| 符号 | 含义 | 示例 | 解释 | 匹配的输入示例 | 
|---|---|---|---|---|
| * | 指定字符重复0次或n次 | (abc)* | 仅包含任意个abc的字符串 | abc、abcabc | 
| + | 指定字符重复1次或n次(至少1次) | m + (abc)* | 以至少1个m开头,后接任意个abc的字符串 | mabc、mabcabc | 
| ? | 指定字符重复0次或1次(至多1次) | m + (abc)? | 以至少1个m开头,后接0个或1个abc的字符串 | mabc、mm | 
| {n} | 只能输入n个字符 | [abcd]{3} | 由abcd中任意字母组成的长度为3的字符串 | abc、acd、bcd | 
| {n,} | 至少指定n个匹配 | [abcd]{3,} | 由abcd中字母组成的任意长度不小于3的字符串 | aab、abd、bbbdca | 
| {n,m} | 至少指定n个但不多于m个匹配 | [abcd]{3,5} | 由abcd中字母组成的任意长度不小于3,不大于5的字符串 | abcd、aabbc | 
代码示例: (此处只示范了a{3,4},其余类似,可自行尝试)
import java.util.regex.Matcher;
import java.util.regex.Pattern;
//正则表达式_元字符_限定符
public class EX03 {
	public static void main(String[] args) {
		String content = "1122aaaaaahelloworld"; 
		
		//注意: java匹配默认贪婪匹配,即尽可能匹配多的
		String regStr = "a{3,4}";  //表示匹配 aaa 或 aaaa
		Pattern pattern = Pattern.compile(regStr);
		Matcher matcher = pattern.matcher(content);
		
		while(matcher.find()) {
			System.out.println("找到 " + matcher.group(0));
		}		
	}
}
 
运行结果:
找到 aaaa
 
2.2.5 定位符
用于规定要匹配的字符串出现的位置
| 符号 | 含义 | 示例 | 解释 | 匹配的输入示例 | 
|---|---|---|---|---|
| ^ | 指定的起始字符 | ^[0-9]+[a-z]* | 以至少1个数字开头,后接任意个小写字母的字符串 | 123、4abc、55cde | 
| $ | 指定结束字符 | ^[0-9]+[a-z]+$ | 以至少1个数字开头,并以至少1个小写字母结尾的字符串 | 1a、123a | 
| \\b | 匹配目标字符串的边界 | ke\\b | 边界指的是字串间有空格或是该目标字符串的结束位置 | kexueke nke | 
| \\B | 匹配目标字符串的非边界 | ke\\B | 与\b相反 | kexueke nke | 
2.3 非贪婪匹配
| 符号 | 解释 | 
|---|---|
| ? | 当该字符紧跟其他限定符后面时,匹配模式为“非贪婪的”。即匹配搜索到的尽可能短的字符串。例如:在字符串“1111”中,“1+?”只匹配单个“1”,而“1+”匹配所有“1” 。 | 
2.4 分组、捕获、反向引用
概念介绍:
- 分组
可以用一个圆括号组成一个匹配模式,这样一个圆括号中的部分我们可以看作是 一个分组。 - 捕获
把分组匹配的内容保存到内存中以数字编号或显式命名的组里,方便之后引用。组0表示整个表达式,第一个出现的分组为组1,第二个为组2,以此类推。 - 反向引用
圆括号的内容被捕获后,之后便可以被使用,这个就叫反向引用。在正则表达式内部的反向引用 \\分组号,外部反向引用 $分组号。 
| 常用的分组构造形式 | 解释 | 
|---|---|
| (pattern) | 非命名捕获。捕获匹配的子字符串,编号从0开始 | 
| (?<\name>pattern) | 命名捕获。将匹配的子字符串捕获到1个组名称或编号名称中,用于name的字符串不能包含标点符号,且不能以数字开头 | 
代码示例:(此处示范 匹配4个连续的相同数字)
import java.util.regex.Matcher;
import java.util.regex.Pattern;
//正则表达式_反向引用
public class EX04 {
	public static void main(String[] args) {
		String content = "1111222abcdddd3333hello";  //目标字符串
		
		//匹配连续4个的相同数字
		String regStr = "(\\d)\\1{3}";   //正则表达式字符串
		Pattern pattern = Pattern.compile(regStr);
		Matcher matcher = pattern.matcher(content); 
			
		while(matcher.find()) {  
			System.out.println("找到 " + matcher.group(0));
		}		
	}
}
 
运行结果:
找到 1111
找到 3333
 
2.5 三个常用类
java.util.regex 包主要包括以下3个常用类
-  
Pattern 类
pattern 类没有公共构造方法,要创建一个 pattern 对象,调用其公共静态方法,它返回一个 pattern 对象。该方法接受一个正则表达式作为它的第一个参数。例如: Pattern r = Pattern.compile(pattern); -  
Matcher类
Matcher 对象是对输入字符串进行解释和匹配的引擎。Matcher 也没有公共构造方法。需调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。 -  
PatternSyntaxException
PatternSyntaxException 是一个非强制性异常类,它表示一个正则表达式模式中的语法错误。 
3. 应用示例
3.1 示例1-电话号码
要求:验证输入的电话号码的格式是否正确
 格式规定:必须以13,14,15,18 开头的11位数,比如 13550358888
 (读者可根据自己的需求灵活变通,此处只是举个例子,不代表所有情况)
代码实现:
import java.util.Scanner;
import java.util.regex.Pattern;
//正则表达式_电话号码
public class EX07 {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		
		//输入需要判断的电话号码
		System.out.print("Enter Phone number: ");
		String content = input.nextLine();
		
		//要求必须以13,14,15,18 开头的11位数
		String regStr = "^1[3|4|5|8]\\d{9}$";
		
		//判断格式是否正确
		System.out.println("The number is: " + Pattern.matches(regStr, content));
		
		input.close();
	}
}
 
运行结果:
Enter Phone number: 13550358888
The number is: true
 
3.2 示例2-电子邮件
要求:验证输入的电子邮件格式是否合法
 格式规定:
- 只能有一个@
 - @前面是用户名,可以是 a-z A-Z 0-9 _ - 字符
 - @后面是域名,且只能为英文字母,如 bilibili.com
 
代码实现:
import java.util.Scanner;
import java.util.regex.Pattern;
//正则表达式_电子邮件
public class EX08 {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		
		//输入需要判断的电子邮件
		System.out.print("Enter email: ");
		String content = input.nextLine();
		
		String regStr = "[\\w-]+@([a-zA-Z]+\\.)+[a-zA-Z]+";
		
		//判断格式是否正确
		System.out.println("The email is: " + Pattern.matches(regStr, content));
		
		input.close();
	}
}
 
运行结果:
Enter email: java@abcd.com
The email is: true
 
4. String类中使用正则表达式
4.1 替换字符串
String 类中包含的 replaceAll 方法可以替换所有匹配的字符串。
代码示例:(此处演示使用正则表达式来替换字符串)
//正则表达式_替换字符串
public class EX05 {
	public static void main(String[] args) {
		String content = "Java8abcdJava11defgjava";  
		
		//使用正则表达式,将Java8和Java11替换成Java
		content = content.replaceAll("Java8|Java11", "Java");
		
		//输出替换后的字符串
		System.out.println(content);
	}
}
 
运行结果:
JavaabcdJavadefgjava
 
4.2 分割字符串
String 类 public String[] split(String regex)
代码示例:(此处演示 如何按照 - 或者 ~ 或者 数字 来分割字符串)
//正则表达式_分割字符串
public class EX06 {
	public static void main(String[] args) {
		String content = new String("jike~hello-world234java");
		
		//要求按照 - 或者 ~ 或者 数字 来分割
		String[] split = content.split("-|~|\\d+");
		
		for(String s : split) {
			System.out.println(s);
		}
	}
}
 
运行结果:
jike
hello
world
java
 
以上为个人自学笔记,学习并借鉴了视频:https://www.bilibili.com/video/BV1Eq4y1E79W?p=1
 以及Java黑皮书: Java语言程序设计与数据结构 基础篇
若有不足,欢迎指正!










