首页 🌐Web

. 号后面跟什么得考虑清楚!!!

分组

在正则表达式中还提供了一种将表达式分组的机制,当使用分组时,除了获得整个匹配。还能够在匹配中选择每一个分组。
要实现分组,使用()即可。
例如:

这段正则表达式将文本分成了两组,第一组为:0731,第二组为8825951
分组有一个非常重要的功能——捕获数据。所以()被称为捕获分组,用来捕获数据,当我们想要从匹配好的数据中提取关键数据的时候可以使用分组,其它数据都不要。
下面来尝试两段正则表达式,来体验分组提取:

  • <div>.*?</div>
  • <div>(.*?)</div>

<div>(.*)</div>

接下来再请你使用分组提取<p> </p>中的数据:

<p>(\w+)</p>

提取学号和提取年月日

学号是由多个关键信息组成的,例如:2019-5013-08 2019表示入学年份,5013为班级代码,08表示班级中的序号。
接下来请你编写正则表达式匹配不同格式的学号,并将其中的关键信息用分组提取出来,需要分成三个分组。

(\d{4})[\s-]?(\d{4})[\s-]?(\d{2})

注意[\s-]?是为了要求的第三条所存在的

再请你使用正则中的分组方式提取所有年月日的数据。

(\d{4})[-/]?(\d{1,2})[-/]?(\d{1,2})

或者条件

使用分组的同时还可以使用或者(or)条件。
例如要提取图片文件的后缀名,可以在各个后缀名之间加上一个|符号:


非捕获分组

有时候,我们并不需要捕获某个分组的内容,但是又想使用分组的特性。
这个时候就可以使用非捕获组(?:表达式),从而不捕获数据,还能使用分组的功能。
例如想要匹配两个字母组成的单词或者四个字母组成的单词就可以使用非捕获分组

获取电话号码

(?:\w)[:-](75855)

分组使用技巧

现在我们想要使用正则表达式将其中的年月日全都提取出来。
可以发现他们唯一的区别就在于分隔符和月份与日期,这个时候可以使用[]来匹配多种情况。
例如:

20200102
2020-01-02
2020-1-2
2020.01.02
2020 01 02
2020 1 2
2020/01/02
(\d{4})[-/.\s]?(\d{1,2})[-/.\s]?(\d{1,2})

就可以从文本中将年月日分别提取出来了。[-./\s]表示匹配三个可能出现的分隔符-./空白?表示匹配它们0次或者1次,其他数据用\d{N}与分组结合就可以提取。

再比如,提取所有电话号码:

[(]?(\d{3})[-).]?(\d{3})[-.]?(\d{4})

分组的回溯引用

正则表达式还提供了一种引用之前匹配分组的机制,有些时候,我们或许会寻找到一个子匹配,该匹配接下来会再次出现。例如,要匹配一段 HTML 代码,比如:0123<font>提示</font>abcd,可能会编写出这样一段正则表达式:

但如果我们将文本<font>提示</bar>

这明显不对,可是表达式不知道它是错的。
我们想让后面分组的正则也匹配font,但是现在所有形式的都会匹配。那如果想让后面分组的正则和第一个分组的正则匹配同样的数据该如何做呢?
这时候就需要用到分组的回溯引用,使用\N可以引用编号为N的分组,因此上述代码可以修改为

通过这个例子,可以发现 \1 表示的就是第一个分组,那么左边的字符就需要括号分组,在这里第一个分组匹配的是 font 所以\1 就代表font
下面让你编写代码匹配符合 ab ba 这种关系的单词

(\w)(\w)\2\1

再请你编写正则表达式匹配下列有重复的数据:

(\w+)(\w+)\1\2

正向先行断言

别名环视、预搜索
先行断言和后行断言总共四种:

  • 正向先行断言
  • 反向先行断言
  • 正向后行断言
  • 反向后行断言

正向先行断言:(?=表达式),指在某个位置向右看,表示所在位置右侧必须能匹配表达式
例如:

如果要取出你好两个字,要求这个你好后面有世界,所以得写:你好(?=世界),这就是正向先行断言

提取包含大小写字母的字符串
先行断言可以用来判断字符串是否符合特定的规则,例如提取包含至少一个大小写字母的字符串:

(?=.*?[a-z])(?=.*?[A-Z]).+ 这段正则表达式规定了匹配的字符串中必须包含至少一个大写和小写的字母

密码强度验证
现在请你编写正则表达式进行密码强度的验证,规则如下:

  • 至少一个大写字母
  • 至少一个小写字母
  • 至少一个数字
  • 至少8个字符

左边为需要你的正则需要匹配的,右边的字符串是你的正则不需要匹配的。

(?=.*?[A-Z])(?=.*?[a-z])(?=.*\d).{8,}

反向先行断言

反向先行断言(?!表达式)的作用是保证右边不能出现某字符。
如果要取出你好两个字,要求这个你好后面没有世界,这个时候就要这么写:你好(?!世界),这就是反向先行断言。

例如:
编写正则表达式匹配不是qq邮箱的数据。

@(?!qq)

匹配标签
编写正则表达式匹配除<p></p>之外的所有标签。

^<(?!p).*
/*非常巧妙!^限定匹配首位,只要第一次出现的不是p标签,剩余的就不用管了,由于默认此处,前后标签一致,所以这样写也行吧*/
<(?![p|/p])
<(?![p|/p]).*>
<((?!p)\w+>)</\1
<(?!p)(.*?)><(?!/p)/\1>
...

正向后行断言

先行断言和后行断言只有一个区别,即先行断言从左往右看,后行断言从右往左看。
正向后行断言:(?<=表达式),指在某个位置向左看,表示所在位置左侧必须能匹配表达式
例如:
如果要取出,要求的前面有,后面有这个世界

让你使用正则表达式匹配匹配王姓同学的名字。

(?<=王).{1,}

反向后行断言

反向后行断言(?<!表达式),指在某个位置向左看,表示所在位置左侧不能匹配表达式
例如:
如果要取出喜欢两个字,要求喜欢的前面没有我,后面没有你,这个时候就要这么写:(?<!我)喜欢(?!你)

匹配一个美元符号中的数据
请使用正则表达式匹配一个$符号中的数据。

(?<!\$)\$[^\$]+\$(?!\$)

匹配两个美元符号中的数据
请使用正则表达式匹配所有两个$符号中的数据。

^\${2}(?!\$)
(?<!\$)[\$]{2}[^\$].*[\$]{2}(?!\$)
...

实践:提取所有人的生日

提取下列数据中所有人的生日,使用两个分组,第一个分组提取“月”,第二个分组提取“日”。

.*?\d{4}[-.年]?(\d{1,2})[-.月]?(\d{1,2})

实践:匹配所有的小数

请编写正则表达式匹配所有的小数:

^\d{1,}\.\d{1,}$

正则真的很简单吗?那是不可能的!




扫描二维码,在手机阅读!
文章评论

    阿鱼咕嘟 访客FireFoxWindows
    2021-05-13 18:48   回复

    我就是儿子

目录