正则表达式(1)

韩顺平老师课程

正则表达式底层实现

案例分析

给定一段文本(字符串),请找出所有四个数字连在一起的子串,如:1998 2020 2021

public static void main(String[] args) {
   
	String context = "1995年,互联网的蓬勃发展给了Oak机会。业界为了使死板、单调的静态网页能够“灵活”起来,……";
	
	 // \\d 表示一个任意的数字
	String regStr = "\\d\\d\\d\\d";
	
	//创建一个模式对象
	Pattern pattern = Pattern.compile(regStr);
	//创建一个匹配器
	Matcher matcher = pattern.matcher(context);
	//开始匹配
	while(matcher.find()){
   
		System.out.println("找到:" + matcher.group(0));
	}		
}
不考虑分组

matcher.find()

  1. 根据指定的规定,定位满足规则的子字符串(比如1995)
  2. 找到后将子字符串开始的索引记录到matcher对象的属性 int[] groups;
    groups[0] = 0,把该子字符串结束的索引(3)+1的值 记录到 groups[1] = 4
  3. 同时记录oldLast 的值为 子字符串的结束的 索引+1的值即4,即下次执行find时,就从4开始匹配

matcher.group(0)

  1. 根据group[0] = 0 和 group[1] = 4 的记录的位置,从context 开始截取子字符串[0,4) 返回
  2. 如果再次执行find方法,仍然按照上面分析来执行
考虑分组

分组:正则表达式中有小括号代表分组,第一个()代表第一组……:(\d\d)(\d\d)

matcher.find()

  1. 根据指定的规定,定位满足规则的子字符串(比如(19)(95))
  2. 找到后将子字符串开始的索引记录到matcher对象的属性 int[] groups;

2.1 groups[0] = 0,把该子字符串结束的索引(3)+1的值 记录到 groups[1] = 4
2.2 记录第一组()匹配到的字符串: groups[2] = 0, groups[3] = 2
2.3 记录第二组()匹配到的字符串: groups[4] = 2, groups[5] = 4
…… ……

matcher.group()
group(0) 表示匹配到的整体的子字符串
group(1) 表示匹配到的子字符串的第一个分组
group(2) 表示匹配到的子字符串的第二个分组
注:分组数不能越界

正则表达式语法

元字符(Metacharacter)

转义号 \\

在使用正则表达式去检索某些特殊字符的时候,需要用到转义符号\\,否则检索不到结果,甚至会报错。
注:在java的正则表达式中,两个\\代表其它语言中的一个\。
需要用到转义符号的字符:.*+()$/?[]^{}
如找到左括号(:\\(

字符匹配符

说明



默认区分大小写

选择匹配符 |

限定符 *+?{n} {n,} {n,m}


定位符

b-结束位置 B开始位置

分组

捕获分组

非捕获分组(特别分组)

不能通过使用matcher.group(1) 进行获取

非贪婪匹配

应用实例

  1. ^[\u0391-\uffe5]+$
  2. ^[1-9]\\d{5}$
  3. ^[1-9]\\d{4,9}$
  4. ^1[3|4|5|8]\\d{9}$
  1. 获取URL: ^(https:// | http://)?([\\w-]+\\. )+[\\w-]+(\\/[\\w-?=&/#%.]*)?$

——解题思路
对于https://www.bilibili.com/video/BV1Eq4y1E79W?p=17
1)确定url的开始部分(可0次或1次):
(https:// | http://)?
2)确定www.bilibili.(字母数字下划线+.)com(字母数字):
([\\w-]+\\. )+[\\w-]
【注:\\w = [0-9a-zA-Z],+ 一个或多个】
3)确定后面的部分(/video/BV1Eq4y1E79W?p=17)【可能有可能没有】:
(\\/[\\w-?=&/#%.]*)?
【注:?在外面0次或1次,在里面就是实实在在的问号(.也是如此);*——0次或多次】

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务