正则表达式
首发:https://mp.weixin.qq.com/s/kS_Vk_sIk9Qaq1IcPWcmVQ
这里只单纯介绍正则表达式,不会涉及其他。
基本的介绍下正则表达式,并讲解一些基本的使用方法和案例。
这篇适用于正则表达式新手入门学习,不讲太多的理论,偏向实战中练习!
先学会怎么用,用的过程中,再探索其中的逻辑。
是什么
正则表达式是什么?
正则表达式(Regular Expression)是用于描述一组字符串特征的模式,用来匹配特定的字符串。通过特殊字符+普通字符来进行模式描述,从而达到文本匹配目的工具。
说白了,正则表达式是一种工具,主要是用来提取和替换字符串。
测试工具
在我们写正则表达式的过程中,我们可能会测试表达式的正确性,这时候就要使用到测试工具
我这里使用的是 RegexTester.exe
请自行下载!
RegexTester基本使用
有2种模式,一个查找一个替换,按照需要选择
查找
填好正则表达式和待匹配的字符串,点击运行即可显示结果
这里说下结果的0,1,2,3,4....
0:表示的就是整个正则表达式匹配到的结果,
1:表示第 1 个括号中匹配到的结果
2:表示第 2 个括号中匹配到的结果
以此类推
替换
替换和查找类似,多了一个替换项,其实就是先查找,将查到的字符串,按照替换项的规则进行替换
$1:表示的是 这里是查找到的第 1 个括号中匹配到的结果
$2:表示的是 这里是查找到的第 2 个括号中匹配到的结果
以此类推
实例详解
就直接上案例了,案例中的所有正则表达式都在图中,我并没有给到可以直接复制粘贴,自己复现一遍,印象更深
复现的过程中,如果有正则语法、元字符、特殊字符等不懂的,可以查看下附表或者自行百度
实例1:
现在有一个待匹配字符串:
构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与运算符可以将小的表达式结合在一起来创建更大的表达式。
需求:匹配其中的表达式
3个汉字
这里我们可以看到,直接用表达式
作为正则表达式即可,我们匹配到了4个地方
实例2:
需求:匹配所有的正则表达式
实例3:
需求:我们要匹配所有的正则表达式
和数据表达式
方法1
我们知道.
可以用来匹配除了换行符外的任意字符,因为表达式
前面2个字符变化的,我们用点来代替
我们可以看到,匹配到了4个结果,不过其中有2个不是我们想要的,优化一下
这样就能得到我们想要的结果了
这里的 [^的]
的意思是匹配除了 的
以外的任意字符
方法2
上面的方式,在当前情况下,是可以匹配到准确的字符串,但是如果换一个,可能匹配到一些我们不需要的字符串,下面我们再精确点
这里正则表达式的意思是:
小括号表示:一个组
竖线|
表示或者的意思
总的就是匹配满足前2个字符是正则
或者数学
,后三个字符是表达式
的字符串
实例4:
源文本:
{ url: "./202108/t20210810_1259734.html", title: '峄城区卫生健康局2021年7月卫生监督行政处罚案件', time: "2021-08-05", source:'', }
{ url: "./202107/t20210721_1249763.html", title: '峄城区市场监管局关于对枣庄越强网络科技有限公司等240家企业', time: "2021-07-22"}
{ url: "./202107/t20210721_1291713.html", title: '行政处罚...', time: "2021-07-22", source:'', }
需求:提取其中所有的url
我们看下我们想要的url有什么特征,第一个是前面有 url:
标识,第二个它们被包含在2个引号之间
所以我们可以这样写
\s*
:表示匹配0到多个任意空白字符
[^"]*?
:表示匹配匹配除"
以外的全部字符,非贪婪匹配 (对于贪婪匹配和非贪婪匹配不了解的可以百度下)
实例5:
源文本:
{ url: "./202108/t20210810_1259734.html", title: '峄城区卫生健康局2021年7月卫生监督行政处罚案件', time: "2021-08-05", source:'', }
{ url: "./202107/t20210721_1249763.html", title: '峄城区市场监管局关于对枣庄越强网络科技有限公司等240家企业', time: "2021-07-22"}
{ url: "./202107/t20210721_1291713.html", title: '行政处罚...', time: "2021-07-22", source:'', }
需求:提取其中所有的title
和实例4差不多
实例6:
源文本:
{ url: "./202108/t20210810_1259734.html", title: '峄城区卫生健康局2021年7月卫生监督行政处罚案件', time: "2021-08-05", source:'', }
{ url: "./202107/t20210721_1249763.html", title: '峄城区市场监管局关于对枣庄越强网络科技有限公司等240家企业', time: "2021-07-22"}
{ url: "./202107/t20210721_1291713.html", title: '行政处罚...', time: "2021-07-22", source:'', }
需求:提取前2个字符是峄城
的title
实例7:
源文本:
{ url: "./202108/t20210810_1259734.html", title: '峄城区卫生健康局2021年7月卫生监督行政处罚案件', time: "2021-08-05", source:'', }
{ url: "./202107/t20210721_1249763.html", title: '峄城区市场监管局关于对枣庄越强网络科技有限公司等240家企业', time: "2021-07-22"}
{ url: "./202107/t20210721_1291713.html", title: '行政处罚...', time: "2021-07-22", source:'', }
需求:提取前2个字符是峄城
的title所对应的url
实例8:
源文本:
{ url: "./202108/t20210810_1259734.html", title: '峄城区卫生健康局2021年7月卫生监督行政处罚案件', time: "2021-08-05", source:'', }
{ url: "./202107/t20210721_1249763.html", title: '峄城区市场监管局关于对枣庄越强网络科技有限公司等240家企业', time: "2021-07-22"}
{ url: "./202107/t20210721_1291713.html", title: '行政处罚...', time: "2021-07-22", source:'', }
需求:提取大括号中的字符串
这种一般主要用来提取行
实例9:
源文本:
{ url: "./202108/t20210810_1259734.html", title: '峄城区卫生健康局2021年7月卫生监督行政处罚案件', time: "2021-08-05", source:'', }
{ url: "./202107/t20210721_1249763.html", title: '峄城区市场监管局关于对枣庄越强网络科技有限公司等240家企业', time: "2021-07-22"}
{ url: "./202107/t20210721_1291713.html", title: '行政处罚...', time: "2021-07-22", source:'', }
需求:有的title中有包含...
,但是我们并不需要
这时候我们就用到正则替换
这里的.
要用\
进行转义,因为在正则中.
默认是匹配除换行符的任意字符
我们要将...
替换为空,所以替换项,我们留空
实例10:
源文本:
{'USCC': '92340503MA2PMQ0T13', 'ID': '2cc5dea5-700a-4724-92f5-b81cd97d0cb5', 'CF_GXRQ': '2021-08-05', 'NAME': '马鞍山市万丰超市'}
需求:将USCC补充成完整的url
完整的url如下:
http://xy.mas.gov.cn/queryDoublePublicInfo?USCC=92340503MA2PMQ0T13
我们可以发现,url后面的USCC=的值,就是源文本中USCC的值,但是现在我们只有源文本,需要自己拼成url,该如何用正则实现呢
第一步:我们先提到源文本中USCC的值
第二步:写替换项
我们提到了USCC的值,用1`,其他的字符不变
实例11:
源文本:
{'USCC': '92340503MA2PMQ0T13', 'ID': '2cc5dea5-700a-4724-92f5-b81cd97d0cb5', 'CF_GXRQ': '2021-08-05', 'NAME': '马鞍山市万丰超市'}
需求:在实例10的基础上,我想直接获取到url
我们是可以先实现实例11中的步骤,让后直接提USCC的值即可,这种就不详细说了,很简单
但是现在想用一个正则替换直接获取到正确的url
因为正则替换是替换你查找到的字符串,没有提到的,不会进行替换,因为我们最后只留下url,所以要不源文本全部提到,进行替换处理
实例12:
源文本:
{'USCC': '92340503MA2PMQ0T13', 'ID': '2cc5dea5-700a-4724-92f5-b81cd97d0cb5', 'CF_GXRQ': '2021-08-05', 'NAME': '马鞍山市万丰超市'}
需求:在实例11的基础上,稍微在复杂一些,同样是直接获取到url
完整的url是这样的:
http://xy.mas.gov.cn/queryDoublePublicInfo?USCC=92340503MA2PMQ0T13&id=2cc5dea5-700a-4724-92f5-b81cd97d0cb5
可以看到这里有2个参数
逻辑其实和上面一样的,就是多了一步,将id的值也提到,进行正则替换
注意
“|”和“[]”的区别:
- 竖线|是或者的关系,竖线两边任意匹配一边都成立
- 中括号[]是括号内部选一的关系,即:括号里面的字符,只要匹配到一个,即成立([]是一个字符集合)
正则中的替换
是将匹配到的数据替换为别的数据,没有匹配到数据是不变的
{1}:表示从0开始数,第一个小括号匹配的内容,
\s\S
和.
的区别
-
\s\S
:匹配全部字符 -
.
:匹配除换行符外的全部字符
附录:正则匹配大全
- ^ 匹配字符串的开头
- $ 匹配字符串的末尾。
- . 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
- [...] 用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k'
- [^...] 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
- re* 匹配0个或多个的表达式。
- re+ 匹配1个或多个的表达式。
- re? 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
- re{ n} 精确匹配 n 个前面表达式。例如, o{2} 不能匹配 "Bob" 中的 "o",但是能匹配 "food" 中的两个 o。
- re{ n,} 匹配 n 个前面表达式。例如, o{2,} 不能匹配"Bob"中的"o",但能匹配 "foooood"中的所有 o。"o{1,}" 等价于 "o+"。"o{0,}" 则等价于 "o*"。
- re{ n, m} 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
- a| b 匹配a或b
- (re) 匹配括号内的表达式,也表示一个组
- (?imx) 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。
- (?-imx) 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。
- (?: re) 类似 (...), 但是不表示一个组
- (?imx: re) 在括号中使用i, m, 或 x 可选标志
- (?-imx: re) 在括号中不使用i, m, 或 x 可选标志
- (?#...) 注释.
- (?= re) 前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。
- (?! re) 前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功
- (?> re) 匹配的独立模式,省去回溯。
- \w 匹配字母数字及下划线
- \W 匹配非字母数字及下划线
- \s 匹配任意空白字符,等价于 [\t\n\r\f].
- \S 匹配任意非空字符
- \d 匹配任意数字,等价于 [0-9].
- \D 匹配任意非数字
- \A 匹配字符串开始
- \Z 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。
- \z 匹配字符串结束
- \G 匹配最后匹配完成的位置。
- \b 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
- \B 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
- \n, \t, 等. 匹配一个换行符。匹配一个制表符。等
- \1...\9 匹配第n个分组的内容。
- \10 匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。
- [\u4e00-\u9fa5] 匹配汉字
更多教程:https://www.runoob.com/regexp/regexp-tutorial.html
关注我获取更多内容