《0基础》学习Python——第十七讲__正则表达式(requests)

avatar
作者
筋斗云
阅读量:8

一、什么是正则表

        正则表达式是一种用于匹配和操作字符串的强大工具。它可以用于检索、替换和验证字符串。正则表达式使用特定的语法来描述字符串的模式,然后用于查找符合该模式的字符串。

        在Python中,可以使用re模块来使用正则表达式。re模块提供了一组函数,包括match()、search()、findall()、finditer()等,用于执行不同类型的匹配操作。

        因为正则表达式也是用字符串表示的,所以首先了解如何用字符来描述字符,如果直接给出字符,就是精确匹配,但有一些字符加上转义符后就具有特殊含义

二、正则表达式元字符

        1、\d  :  可以匹配一个数字,例如:'00\d'可以匹配'007',但无法匹配'00A','\d\d\d'可以匹配'010'

        2、\w :可以匹配一个字母或数字,例如:'\w\w\d'可以匹配'py3'

        3、'.'  :点可以匹配除\n,\r的任意单个字符,例如:'py.'可以匹配'pyc'、'pyo'、'py!'等等

        4、\s  :可以匹配任何不可见字符,包括空格、制表符、换页符等

        5、\D :匹配一个非数字字符,等价于 [^0-9 ]

        6、\S :匹配可见字符,[^\f\n\r\t\v]

        7、\W:匹配任何非单词字符,[^A-Za-z0-9_ ]

        8、\b :匹配一个单词的边界,指单词和空格间的位置

        9、\B:匹配非单词边界,"er\B"能够匹配"er",但不能匹配"never"中的er

        10、\f:换页符

        11、\n:换行符

        12、\r:回车符

        13、\t:制表符

        14、\v:垂直制表符        

三、匹配长字符串

        要匹配变长的字符,在正则表达式中,用 * 表示任意个字符(包括0个),用 + 表示至少一个字符,用 表示0个或1个字符,用{n}表示n个字符,用{n,m}表示n~m个字符

        [xyz]:字符集合,匹配所包含的任意一个字符,eg:[abc],即只能匹配abc中的一个字符

        [a-z]:字符范围,匹配指定范围的任意字符,如:[A-Z],即可匹配一个A-Z之间的大写字母

        [0-9]:数字范围,匹配指定范围的任意数字一个

        

        *:匹配前面的子表达式任意次 ,即>=0

        +:匹配前面的子表达式一次或多次,即>=1

        ?:匹配前面的子表达式一次或零次,即0或1

        ^:匹配输入的字符首,即限制开头,^\d表示必须以数字开头

        $:匹配输入的字符尾,即限制结尾,\d$表示必须以数字结束

        {n}:n是一个非负整数,匹配确定的n次

        {n,}:n是一个非负整数,至少匹配n次

        {n,m}:n是一个非负整数,最少匹配n次,最多匹配m次

        A|B可以匹配A或B,所以(P|p)ython可以匹配'Python'或者'python'

        

        在正则中 - 表示从什么到什么,[ ] 表示范围,例如:

                [0-9a-zA-Z\_]  可以匹配一个数字、字母或者下划线

                [0-9a-zA-Z\_]+  可以匹配至少由一个数字、字母或者下划线组成的字符串,比如'a100','0_Z','Py3000'等

                [a-zA-Z\_][0-9a-zA-Z\_]*  可以匹配由字母或下划线开头,后接任意个由一个数字、字母或者下划线组成的字符串,也就是Python合法的命名规则

                [a-zA-Z\_][0-9a-zA-Z\_]{0, 19}  更精确地限制了长度是1-20个字符(前面1个字符,后面最多19个字符)

        

四、mach()可以判断正则表达式是否匹配

        在正则表达式中,match()是用于从字符串的起始位置开始匹配模式的函数。它尝试从字符串的开头匹配正则表达式模式,如果匹配成功则返回一个Match对象,否则返回None

  Match对象包含了匹配的结果以及其他相关信息,可以通过调用group()方法来获取匹配的字符串。如果正则表达式中包含了分组,可以通过传递分组索引或分组名称给group()方法来获取特定的分组匹配结果。

例如:

        re.match(r'^\d{3}\-\d{3,8}$', '010-12345')

        调用match方法,左边需要传入一个正则表达式,右边为待匹配的字符串,如果能匹配上则返回:

        <_sre.SRE_Match object; span=(0, 9), match='010-12345'>

        re.match(r'^\d{3}\-\d{3,8}$', '010 12345') 无法匹配则返回空,None

        match方法通常会结合if选择结构进行判断

        

五、re模块

        re模块是Python中内置的用于处理正则表达式的模块。它提供了一系列函数和方法,用于对字符串进行匹配、搜索、替换等操作。通过导入re模块,可以使用正则表达式相关的功能,如编译正则表达式、匹配和搜索字符串、提取匹配结果等。re模块使得在Python中使用正则表达式变得非常方便和灵活。

        注意:s = 'ABC\\-001' ,s类型为str,即Python最基本的字符串,由于'\'会对'\'进行转义,故对应的正则表达式字符串变成:'ABC\-001'

        Python中为字符串提供了一种特殊的语法标记:r'abcdefg\hijklmn',如果使用r标记字符串,那么就不再需要考虑转义的问题了:s = r'ABC\-001',对应的正则表达式字符串不变:'ABC\-001'

        推荐Python中进行正则表达式匹配时,使用r前缀标记字符串 

        import re 使用前需要先导入re模块

六、用例解析

案例一匹配一串电话号码

        其中的r"\d{4}-\d{3,8}"表示的是电话号码,其中r表示防止双引号内有转置字符,\d表示一个数字,而后面的{4}则表示前一个\d的次数为4,即匹配四个数字,之后 - 表示特指这个字符,即必须匹配这个特定字符,之后的\d{3,8}则表示要匹配3个以上8个以下的数字,包含3和8

phone_num = "0551-1234567899" print(re.match(r"\d{4}-\d{3,8}", phone_num))

其打印结果为

案例二, split ( ) 切分字符串

strs = "a,b;c@d"     print(re.split(r'[,;@]', strs))

       正常我们都知道split的用法,便是 "1-2-3".split( ' - ' ),其打印结果为列表['1','2','3'],因为str自带的split方法,无法识别连续的空格, 但是re模块中的split方法无论多少个空格都可以正常分割,如上代码所述,即调用request类中的用法split,将字符串str中需要分隔的字符写出来分隔str字符串,得到的结果为 [a,b,c,d]

案例三、匹配出时间(分组group:元组形式打印)

        除了简单地判断是否匹配之外,正则表达式还有提取子串的强大功能。用()表示的就是要提取的分组(Group),比如:^(\d{3})-(\d{3,8})$分别定义了两个组,可以直接从字符串中提取出区号和本地号码

如果正则表达式中定义了组,就可以在Match对象上用group()方法提取出子串来注意group(0)永远是与整个正则表达式相匹配的字符串,group(1)、group(2)...表示第1、2、……个子串
    t = "19:59:59"     # 匹配出时间     # 分组使用的是在正则内部使用 括号 第几个括号就是第几个组别     print(re.match(r"([0-1]\d|2[0-3]):([0-5]\d):([0-5]\d)", t).groups())

解析其中的  r"([0-1]\d|2[0-3]):([0-5]\d):([0-5]\d)",

[0-1]表示匹配0到1的一个数字,\d表示匹配一个数字,他们俩联合起来就是匹配00到19的一个数字,后面的 | 则表示或的作用,指定了一个数2开头,0到3结尾的数字,即表示20到23之间的数字,[0-1]\d|2[0-3]他们两个用 | 符号或起来则表示匹配00到23之间的数字,之后的:号也表示指定匹配字符,以及 [0-5]\d 则同样表示0到5的数字后面结尾0到9的数字,合起来就是0到59的数字。

但是为什么要这么多呢,用一个普通的代码也可匹配例如:

t='19:59:59' reponse=re.match(r"\d\d:\d\d:\d\d",t) print(reponse)

其输出结果为:

同样可以匹配出时间,但是如果更改一下时间呢,代码如下:

t='95:66:59' reponse=re.match(r"\d\d:\d\d:\d\d",t) print(reponse)

其同样可以匹配成功,但是代码正确,逻辑不正确,时间的表示范围不对,所以必须要限制范围去匹配,使匹配更精准。

七、贪婪匹配

        正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符

        例如,匹配出数字后面的0:

re.match(r'^(\d+)(0*)$', '102300').groups()

        最终结果:('102300', '')

        由于\d+采用贪婪匹配,直接把后面的0全部匹配了,结果0*只能匹配空字符串

        必须让\d+采用非贪婪匹配(也就是尽可能少匹配),才能把后面的0匹配出来,加个?就可以让\d+采用非贪婪匹配:

re.match(r'^(\d+?)(0*)$', '102300').groups()
最终结果:('1023', '00')

八、编译

        当在Python中使用正则表达式时,re模块内部会干两件事情:编译正则表达式,如果正则表达式的字符串本身不合法,会报错,用编译后的正则表达式去匹配字符串

        如果一个正则表达式要重复使用几千次,出于效率的考虑,可以使用compile方法预编译该正则表达式,接下来重复使用时就不需要编译这个步骤了,直接匹配:

import re # 导入模块 re_telephone = re.compile(r'^(\d{3})-(\d{3,8})$')#预编译  print(re_telephone.match('010-12345').groups()) # 进行匹配并返回所有组  print(re_telephone.match('010-8086').groups()) # 进行匹配并返回所有组

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!