正则表达式 底层实现
https://www.bilibili.com/video/BV1Eq4y1E79W/?p=3
示例:找出所有四个数字连在一起的子串
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegTheory {
public static void main(String[] args) {
String content = "1998年12月8日,第二代Java平台的企业版J2EE发布。" +
"1999年6月,Sun公司发布了第二代Java平台(简称为Java2)的3个版本:J2ME(Java2 Micro Edition,Java2平台的微型版)," +
"应用于移动、无线及有限资源的环境;J2SE(Java 2 Standard Edition,Java 2平台的标准版),应用于桌面环境;" +
"J2EE(Java 2Enterprise Edition,Java 2平台的企业版),应用3443于基于Java的应用服务器。" +
"Java 2平台的发布,是Java发展过程中最重要的一个里程碑,标志着Java的应用开始普及9889";
/**
* 目标:匹配所有四位的数字
* 说明
* 1、\\d 表示一个任意的数字
*/
String regStr = "\\d\\d\\d\\d";
//2、创建模式对象
Pattern pattern = Pattern.compile(regStr);
/**
* 3、创建匹配器
* 说明:创建匹配器 matcher,按照正则表达式的规则,取匹配 content 字符串
*/
Matcher matcher = pattern.matcher(content);
//4、开始匹配
while (matcher.find()) {
System.out.println("找到:" + matcher.group(0));
}
}
}
找到:1998
找到:1999
找到:3443
找到:9889
https://www.bilibili.com/video/BV1Eq4y1E79W/?p=4
matcher.find() 完成的任务
/**
* matcher.find() 完成的任务
* 1、根据指定的规则,定位满足规则的子字符串(比如:1998)
* 2、找到后,将子字符串的开始下标记录到 matcher 对象的属性 int[] groups;
* groups[0]=0,把该子字符串的结束下标+1的值记录到 group[1] = 4
* 3、同时记录 oldLast 的值为子字符串的下标+1的值即4,即下次执行matcher.find()时,就从4开始匹配
*
* matcher.group(0) 分析
*
* 源码:
* public String group(int group) {
* if (first < 0)
* throw new IllegalStateException("No match found");
* if (group < 0 || group > groupCount())
* throw new IndexOutOfBoundsException("No group " + group);
* if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
* return null;
* return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
* }
* 1、根据 groups[0] = 0 和 groups[1] = 4 的记录的位置,从 content 开始截取子字符串返回
* 就是[0,4) 包含0 但是不包含下标为4的位置
*
* 如果再次指向 find 方法,仍然按上面分析来执行
*/
while (matcher.find()) {
System.out.println("找到:" + matcher.group(0));
}
断点调试,观察、验证整个过程
https://www.bilibili.com/video/BV1Eq4y1E79W/?p=5
matcher.group(0)、matcher.group(1)……分组的概念
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegTheory1 {
public static void main(String[] args) {
String content = "1998年12月8日,第二代Java平台的企业版J2EE发布。" +
"1999年6月,Sun公司发布了第二代Java平台(简称为Java2)的3个版本:J2ME(Java2 Micro Edition,Java2平台的微型版)," +
"应用于移动、无线及有限资源的环境;J2SE(Java 2 Standard Edition,Java 2平台的标准版),应用于桌面环境;" +
"J2EE(Java 2Enterprise Edition,Java 2平台的企业版),应用3443于基于Java的应用服务器。" +
"Java 2平台的发布,是Java发展过程中最重要的一个里程碑,标志着Java的应用开始普及9889";
/**
* 目标:匹配所有四位的数字
* 说明
* 1、\\d 表示一个任意的数字
*/
String regStr = "(\\d\\d)(\\d\\d)";
//2、创建模式对象
Pattern pattern = Pattern.compile(regStr);
/**
* 3、创建匹配器
* 说明:创建匹配器 matcher,按照正则表达式的规则,取匹配 content 字符串
*/
Matcher matcher = pattern.matcher(content);
//4、开始匹配
/**
* matcher.find() 完成的任务 (考虑分组)
* 什么是分组?
* 比如:(\d\d)(\d\d),正则表达式中有() 表示分组,第1个()表示第1组,第2个()表示第2组,……
* 1、根据指定的规则,定位满足规则的子字符串(比如:(19)(98))
* 2、找到后,将子字符串的开始下标记录到 matcher 对象的属性 int[] groups;
* 2.1、groups[0] = 0,把该子字符串的结束下标+1的值记录到 groups[1] = 4;
* 2.2、记录1组()匹配到的字符串 groups[2] = 0 groups[3] = 2
* 2.3、记录2组()匹配到的字符串 groups[4] = 2 groups[5] = 4
* 2.4、如果有更多的分组……
* 3、同时记录 oldLast 的值为子字符串的结束下标+1的值,下次执行 matcher.find()时,就从 oldLast 开始匹配
*/
while (matcher.find()) {
System.out.println("找到:" + matcher.group(0));
System.out.println("找到1组:" + matcher.group(1));
System.out.println("找到2组:" + matcher.group(2));
System.out.println();
}
}
}
找到:1998
找到1组:19
找到2组:98
找到:1999
找到1组:19
找到2组:99
找到:3443
找到1组:34
找到2组:43
找到:9889
找到1组:98
找到2组:89
小结
1、如果正则表达式有() 即分组
2、取出匹配的字符串规则如下:
group(0) 表示匹配到的子字符串
group(1) 表示匹配到的子字符串的第1组子串
group(2) 表示匹配到的子字符串的第2组子串
……
但是分组的数不能越界