正则和re模块

正则和re模块
程序领域做了哪些事
1.表单验证:登陆注册页面使用的表单验证 web开发 要求简单语法
2.爬虫
3.自动化开发,日志分析

什么是正则表达式:一种匹配字符串的规则

明确一件事:
正则表达式是一种独立的语法
和Python没有关系

要先学习正则表达式语法,再学习使用python来操作正则

帮助学习的工具:http://tool.chinaz.com/regex

正则表达式
基础知识
什么是正则
应用领域
正则表达式的语法
元字符
字符组:[] 非字符组:[^] 或:| 分组:(): 约束在一个字符的位置上能出现的内容,是一个范围
[1bc] 是一个范围
[0-9]|[a-b]|[A-B] 匹配三个字符
[0-9A-Za-z] 匹配一个字符串
[A-z] 匹配一个字符串
| ‘或’ 用法 [1-9]\d{16}[0-9X]|[1-9]\d{14} 身份证号18位|15位(18位在前,15位在后,也就是说长的写在前边,短的在后边)
() 分组 用法 [1-9]\d{14}(\d{2}[1-9X])? 身份证号,15位,或者后边可以有或没有3位
d+(.\d+)? 整数或者小数
\d == [0-9] 匹配一个 也表示匹配一个字符,匹配的是一个数字
\D 匹配非数字
\w == [0-9a-zA-Z] 也表示匹配一个数字字母下划线(有漏洞,不完全等于.俄文中的a也能匹配进去)
\W 匹配非数字字母下划线
\s == [\n \t] 匹配所有的空白符(回车.空格.制表符)
\n 换行符
\t 制表符
\S 匹配非空白
[\d\D] [\w\W] [\s\S] 匹配所有
^ 开始
$ 结尾
. 除换行符之外的任意字符,爬虫容易用,表单不容易用

    量词
        *       重复0到多次
        +       重复1到n次
        ?       重复0次或1次
        {n}     重复n次
        {n,}    重复n次或多次
        {n,m}   重复n次到m次
    特殊的用法和现象
        ?的使用
            1. 在量词的后面跟了一个?,取消贪婪匹配,非贪婪(惰性)模式
                ??
                *?
                +?
                {n}?
                最常用: 李.*?X      匹配'李'开始,后边任意字符,直到找到一个x后停止.

其他知识:
    元字符
    元字符+量词:  贪婪匹配(回溯算法)
    元字符+量词+? 惰性匹配(量词后面加?)

在python中使用正则表达式:
转义符:
一. 正则表达式中的转义:
1. \转义字符: 如 ‘(’ 表示匹配小括号
2. [()+*/?$.] 在字符组中一些特殊的字符会现出原形
3. 所有的\d \D \w \W \s \S \t \n 都表示它原本的意义
4. [-]只有写在字符组的首位的时候表示普通的减号
写在其他位置的时候表示范围[1-9][a-z]
如果单独想匹配减号,这么写[9-1]
二. 在Python中使用正则表达式
r 指定不转义,如:
print(r’\n’) >>> \n
print(r’\n’) >>> \n
re模块:
1.匹配:
(1)findall(‘正则’,’字符串’)
# 参数说明:
返回值类型:列表
返回值个数:1
返回值内容:所有匹配上的项,无匹配项返回空列表[]
实例1:(有返回值)
# ret = re.findall(‘\d+’, ‘12454adasdasd114557’)
# print(ret)
# 结果 >>> [‘12454’, ‘114557’]

            实例2:(无返回值)
            # ret = re.findall('\s+', '12454adasdasd114557')  # 匹配任意空白符
            # print(ret)
            # 结果 >>> []
        (2)search('正则','字符串')
            # 参数说明:
                返回值类型: 正则匹配结果的对象
                返回值个数:1
                返回内容:如果匹配上了就返回对象,如果没匹配上返回None
            实例1:(有返回值)
            # ret2 = re.search('\d+','@$19874ashfk01248')
            # print(ret2)
            # # 结果 >>> <_sre.SRE_Match object; span=(2, 7), match='19874'>
                                             其中span中的分别是(匹配项的开始索引,结束索引+1)
                                             match中的是(找到的匹配项)
            # if ret2:print(ret2.group()) # 返回的对象通过group来获取匹配到的第一个结果,如果None.group()会报错,所以需要if判断下.
            # # 结果 >>> 19874

            实例2:(无返回值)
            # ret3 = re.search('\s+','19874ashfk01248')
            # print(ret3) #  返回值类型: None   如果没有匹配上就是None
            # # 结果 >>> None

        (3)match('正则','字符串')   ==>相当于search('^正则','字符串')(相当于search中的正则表达式中添加个^起始符号)
            match只能匹配是否式以正则表达式开头的.其他的和search一样.
            也就是说search可以替代match

            实例1:(有返回值)
            # ret4 = re.match('\d+', '158954asdasdas1545')
            # print(ret4)
            # # >>>结果 <_sre.SRE_Match object; span=(0, 6), match='158954'>

            实例2:(无返回值)
            # ret5 = re.match('\d+', '%122sdas1212')
            # print(ret5)
            # # >>>结果 None (开头匹配不上'\d+',所以返回None)

    2.替换:
        (1)sub('正则', '替换成的新字符串', '字符串', 替换的次数int)
            # 参数说明:
                返回值类型: 替换后的字符串
                返回值个数:1
                返回内容:如果匹配上了就把替换上的内容替换成需要替换成的字符串,返回回来.
                         如果没有匹配上,就把原来的内容返回回来.

            实例1:(replace)
            # print('replace789,24utdeedeeeeshf'.replace('e','H',3))
            # # >>>结果 rHplacH789,24utdHedeeeeshf  (把e替换成H,替换3个)

            实例1:(默认参数)
            # ret = re.sub('\d+','H','replace789nbc2xcz392zx')
            # print(ret)
            # # >>>结果 replaceHnbcHxczHzx  (把数字替换成H)

            实例1:(带替换次数)
            # ret = re.sub('\d+','H','replace789nbc2xcz392zx,48495',1)
            # print(ret)
            # # >>>结果 replaceHnbc2xcz392zx,48495  (把数字替换成H,替换1次)

        (2)subn('正则', '替换成的新字符串', '字符串')
             # 参数说明:
                返回值类型: 元组(替换后的字符串, 替换了的次数)
                返回值个数:1个元组(2个值)
                返回内容:如果匹配上了就把替换上的内容替换成需要替换成的字符串,和替换了几处以元组的形式返回来.
                         如果没有匹配上,就把原来的内容和替换了0处以元组的形式返回来.即('原字符串', 0)

            实例1:
            # ret = re.subn('\d+','H','replace789nbc2xcz392zx')
            # print(ret)
            # # >>>结果 ('replaceHnbcHxczHzx', 3)   (把所有匹配到的数字替换成H,返回替换结果和替换的次数)

    3.切割:
        (1)split('正则','字符串')
            # 参数说明:
                返回值类型: 列表[切割后的字符串]
                返回值个数:1个字符串
                返回内容:如果匹配上了就以匹配上的内容进行切割,然后形成列表.
                         如果没有匹配上,就把原来的内容和替换了0处以元组的形式返回来.即('原字符串', 0)

            实例1:(split)
            # print('alex|83|'.split('|'))
            # # >>>结果 ['alex', '83', '']

            实例2:()
            # ret = re.split('\d+','alex83egon20taibai40')    # 以数字切割
            # print(ret)
            # # >>>结果 ['alex', 'egon', 'taibai', '']

正则表达式进阶
进阶方法–爬虫/自动化开发
1.compile(‘正则表达式’) 时间效率(只有在多次使用某一个相同的正则表达式的时候,这个compile才会帮助我们提高程序的效率)
# re.findall(‘-0.\d+|-[1-9]+(.\d+)?’,’alex83egon20taibai40’) # –> python解释器能理解的代码 –> 执行代码
实例1:()
# ret = re.compile(‘-0.\d+|-[1-9]\d+(.\d+)?’) # 通过re.compile 把正则编译成python解释器能理解的代码,赋值给ret
# res = ret.search(‘alex83egon-20taibai-40’) # 通过ret调用search(需要匹配的字符串)
# print(res.group())
# # >>>结果 -20

    2.finditer('正则','字符串')    空间效率
        (1)# 参数说明:
            返回值类型: 可迭代对象
            返回值个数: 1个可迭代对象
            返回内容:如果匹配上了就返回一个可迭代对象,可以使用for循环取出来.
                     如果没有匹配上,可迭代对象为空,取不到值,但不报错.

        (2)实例1:(findall)
        # print(re.findall('\d','sjkhkdy98ufejwsh2yujfpwcmc'))
        # # >>>结果 ['9', '8', '2']

        (3)实例2:(finditer)
        # ret = re.finditer('\d','sjkhkdy98ufejwsh2yujfpwcmc')
        # for r in ret:
        #     print(r.group())
        # # >>>结果 9
        # # >>>结果 8
        # # >>>结果 2

    3.所有的空间效率的提升,都伴随着时间效率的提升

    4.python中的正则表达式
        (1)findall 会优先显示分组中的内容,要想取消分组优先,要这样:(?:正则表达式):如
           findall和split 中会有这个问题,search不会有这个问题.
            实例1:(findall正常匹配查找)
            # ret = re.findall('www.baidu.com|www.oldboy.com','www.oldboy.com')
            # print(ret)      # 正常匹配,结果正常
            # # >>>结果 ['www.oldboy.com']

            实例2:(findall匹配查找中加分组)
            # ret = re.findall('www.(baidu|oldboy).com','www.oldboy.com')
            # print(ret)      # 匹配规则中有分组(),那么匹配成功后,只显示分组中的内容
            # # >>>结果 ['oldboy']

            实例3:(findall匹配查找中分组取消优先显示)
            # ret = re.findall('www.(?:baidu|oldboy).com','www.oldboy.com')
            # print(ret)      # 要想全部显示,在匹配规则中写上?:来取消分组优先显示
            # # >>>结果 ['www.oldboy.com']

            实例4:(findall匹配查找中加分组)
            ret = re.findall('-0\.\d+|-[1-9]\d*(\.\d+)?','-1asdada-200')
            print(ret)  # 正常匹配到了-1和-200,但是都不是".数字"的格式,所以显示为空
            # >>>结果 ['', '']

            实例5:(练习:打印出字符串中的整数(想要的和不想要的在一块,用来区分))
            # ret = re.findall(r'\d+(?:\.\d+)|(\d+)','1-2*(60+(-40.35/5)-(-4*3))')
            # print(ret)      # 匹配到"\d+(?:\.\d+)"是小数,匹配到"(\d+)"是整数,是小数不优先显示,是整数优先显示,所以小数显示位空
            # # >>>结果 ['1', '2', '60', '', '5', '4', '3']
            # ret.remove('')      # 删除列表中的空
            # print(ret)
            # # >>>结果 ['1', '2', '60', '5', '4', '3']

            实例6:(练习)
            # ret = re.findall('>(\w+)<',r'<a>wahaha<\a>')
            # print(ret)
            # # >>>结果 ['wahaha']

        (2)split 遇到分组,会保留分组内被切掉的内容
            实例1:(正常split)
            # ret = re.split('\d+','alex83egon20taibai40')
            # print(ret)      # 正常切割,会切掉匹配到的内容
            # # >>>结果 ['alex', 'egon', 'taibai', '']

            实例1:(split带分组)
            # ret = re.split('(\d+)', 'alex83egon20taibai40')
            # print(ret)      # 匹配规则加上分组后,切割后返回的内容会保留匹配到的内容.
            # # >>>结果 ['alex', '83', 'egon', '20', 'taibai', '40', '']

        (3)search 如果search中有分组的话,通过group(n)就能拿到group中的匹配的内容
            实例1:(分组遇见search)
            # ret = re.search('\d+(.\d+)(.\d+)(.\d+)?','1.2.3.4-2*(60+(-40.35/5)-(-4*3))')
            # print(ret.group())
            # # >>>结果 1.2.3.4
            # print(ret.group(0))     # 默认参数是0,显示匹配到的全部
            # # >>>结果 1.2.3.4
            # print(ret.group(1))     # 显示匹配到的分组中的第1个分组对应的数值
            # # >>>结果 .2
            # print(ret.group(2))     # 显示匹配到的分组中的第2个分组对应的数值
            # # >>>结果 .3
            # print(ret.group(3))
            # # >>>结果 .4

            实例2(练习,找到标签中的内容):
            # ret = re.search(r'<(\w+)>(\w+)</(\w+)>',r'<a>wahaha</b>')
            # print(ret.group())
            # # >>>结果 <a>wahaha</b>     # 但是这样找到的结果<a>和</b>本不是一对标签,但是被找到了,不是我想要的,所以只能通过分组命名来解决了
            # print(ret.group(1))
            # # >>>结果 a
            # print(ret.group(2))
            # # >>>结果 wahaha

分组命名
    (?P<name>正则表达式) 表示给分组起名字
    (?P=name) 表示使用这个分组,这里匹配到的内容应该和分组中的内容完全相同

        实例1:
        # ret = re.search("<(?P<name>\w+)>\w+</(?P=name)>","<h1>hello</h1>")
        # print(ret.group('name'))
        # # >>>结果 :h1
        # print(ret.group())
        # # >>>结果 :<h1>hello</h1>

    通过索引使用分组:
        \1  表示使用第一组,匹配到的内容必须和第一个组中的内容完全相同

        实例2:
        # ret = re.search(r"<(\w+)>(\w+)</\1>","<h1>hello</h1>")    # </\1> 指的是(\w+)
        # print(ret.group(1))
        # # >>>结果 :h1
        # print(ret.group(2))
        # # >>>结果 :hello
        # print(ret.group())
        # # >>>结果 :<h1>hello</h1>

       实例3:
        # ret = re.search(r'<(?P<tag>\w+)>(?P<c>\w+)</(\w+)>',r'<a>wahaha</b>')
        # print(ret.group())
        # # >>>结果 :<a>wahaha</b>
        # print(ret.group('tag'))     # 分组命名后,可以使用名称访问也可以使用n来访问
        # print(ret.group(1))
        # # >>>结果 :a
        # print(ret.group('c'))
        # print(ret.group(2))
        # # >>>结果 :wahaha
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值