第十六讲 python学习总结----正则表达式、内存管理、单元测试

1、正则表达式
1、原始正则
在正则表达式的前面加上一个r,匹配\d的时候只需要加一个\让\d失去意义即可
普通字符串前面加r,让字符串中所有有意义的全部失去意义
推荐:以后写正则,前面都加上r

import re
a = re.compile(r'\n')
b = 'i love6\d y\nou'
ret = a.search(b)
print(ret.group())

2、数量词
作用:数量词是用来修饰前面单字符的,修饰的作用在于控制前面单字符出现的次数
{m} 限制前面的字符只能出现m次
{m,} 限制前面的字符出现的次数为最少m次
【注】正则表达式中的字符都是有意义的,空格不要乱加
{m,n} 限制前面的字符出现的次数最少为m次,最多为n次
* 限制前面的字符出现的次数为任意多次 {0,}
+ 限制前面的字符出现的次数为至少1次 {1,}
? 修饰前面的字符是可有可无 {0,1}

import re

# pattern = re.compile(r'\w{1,}\d{4}')
# pattern = re.compile(r'\w{0,1}\d{4}')
# string = 'a0001,0001,我是lalalallalalallalalala0002,收到请回答,地雷买好了吗'

# pattern = re.compile(r'\S*\W{2}\d{3}')
# pattern = re.compile(r'\w{4}\W\d+\W{2}\w{2}\S*')
# pattern = re.compile(r'\w{4}\S+')
pattern = re.compile(r'[\w-]+\$#\d+')
string = 'i love you very-100--__$#918 much lalala dududu nenene xixixi hehe'
ret = pattern.findall(string)

print(ret)

3、边界修饰符
^ 字符串必须以后面的正则表达式开头
必须写到正则的最前面
g o u d a n 该正则的意思是只能匹配字符串goudan,如果想匹配既以goudan开头,又以goudan结尾的字符串,正则写法如下 ^goudan.*goudan$
\b 词边界,\W的范围都是词边界
\B 非词边界


import re
pattern = re.compile(r'^goudan[\w\s]+goudan$')  
#以goudan开头 大于等于1个数字字母下划线空格 goudan结尾还可以写成以下格式
#pattern = re.compile(r'^goudan.*goudan$')
string = 'goudan baby123hahalove goudan'
ret = pattern.search(string)
print(ret.group())


import re 
pattern = re.compile(r'\bis\b')  #\b词边界,边界另一侧不可能有字符了,如果有字母则就不是边界了
string = 'sheis a girl, he is a gay, isit?'
ret = pattern.findall(string)
print(ret)                       #输出的结果是中间的is


import re 
pattern = re.compile(r'\Bis\b')#\B非词边界 \b词边界 is的左边可以有字符右边不可以有
string = 'sheis a girl, he is a gay, isit?'
ret = pattern.findall(string)
print(ret)                    #输出的is是第一个is

4、匹配分组
| 或者的关系 两边的正则只要匹配一个成功就成功
()
作用1:视为一个整体
作用2:子模式
一个小括号就是一个子模式,当使用findall的时候,子模式匹配成功的内容会列出到元组中,当时用match、search的时候,子模式匹配到的内容需要通过ret.group(1) 来获取
\num
取出第num个子模式匹配到的内容原封不动的写到这里即可
取出子模式第二种用法,通过名字进行获取
(?P正则表达式)
引用的时候 (?P=goudan)

'''
#| 或者
import re
pattern =re.compile(r'\d+|[a-z]{5}') #|是或者
string = '16789hello world'
#string = 'hello world'
ret =pattern.search(string)
print(ret)

#()整体
import re
#pattern =re.compile(r'\d+|[a-z]{5}') 
pattern = re.compile(r'(\d+|[a-z]){5}') #里面小括号 正则整体重复5遍
string = '1-a2-z3-yhello baby'
ret = pattern.search(string)     
print(ret)

 #括号内|
#pattern = re.compile(r'(\d-[a-z]|[A-Z]#){3}')  #\d-[a-z]重复3遍或[A-Z]#重复3遍
#pattern = re.compile(r'(\d-[a-z]|[A-Z]#)*')    #数量修饰词都可以
#举例
import re
pattern = re.compile(r'(\d-[a-z]|[A-Z]#){3}')
string = 'A#1-zC#hello baby'
ret = pattern.search(string)     
print(ret) 


#括号里的( )子模式 findall

import re
pattern = re.compile(r'(\d-[a-z]|[A-Z]#)+love')
string = 'A#1-zC#lovehello babyc#2-plove'
ret = pattern.findall(string)     
print(ret) 
#search输出A#1-zC#love 2-plove findall未输出A#1-zC#love 2-plove ? 需要加括号
import re
pattern = re.compile(r'((\d-[a-z]|[A-Z]#)+love)')#变成两个参数
string = 'A#1-zC#lovehello babyc#2-plove'
ret = pattern.findall(string)     
print(ret)

#pattern = re.compile(r'(\d-[a-z]|[A-Z]#)+(love)') #变成三个参数 三个括号匹配三个内容


#search如何获取子模式
import re
pattern = re.compile(r'(\d-[a-z]|[A-Z]#)+(love)')#变成两个参数
string = 'A#1-zC#lovehello babyc#2-plove'
ret = pattern.search(string)     
print(ret.group())
print(ret.group(1))
print(ret.group(2))



#需要的是<dudu><mememe>今天学习的正则好简单呀</mememe></dudu>
#string变化也能取出  不符合要求<dudu>必须对应<dudu>
import re 
#pattern = re.compile(r'<[a-z]+><\w+>\w+</\w+><\w+>')
pattern = re.compile(r'(<[a-z]+>)+\w+(</\w+>)+')
string = 'hahahaha<dudu><mememe>今天学习的正则好简单呀</mememe></dudu>lalalala'
#string = 'hahahaha<dudu><mememe>今天学习的正则好简单呀</mememe></nunu>lalalala'
ret = pattern.search(string)
print(ret.group())
#print(ret.group(1))
#print(ret.group(2))





# 子模式使用
#可以取出<dudu><mememe>今天学习的正则好简单呀</mememe></dudu>
import re 
   #第一种写法  \number
# pattern = re.compile(r'<([a-z]+)><(\w+)>\w+</\2></\1>')
    #(r'<([a-z]+)第一个子模式匹配的内容和\1相同 ,(\w+)第二个子模式匹配的内容和\2相同
   #第二种写法   起别名的方式
pattern = re.compile(r'<(?P<goudan>[a-z]+)><(?P<shidan>\w+)>\w+</(?P=shidan)></(?P=goudan)>')
   #(?P<goudan>[a-z]+)  别名为goudan  (?P<shidan>\w+)
string = 'hahahaha<dudu><mememe>今天学习的正则好简单呀</mememe></dudu>lalalala'
ret = pattern.search(string)
print(ret.group())
# print(ret.group(1))
# print(ret.group(2))
'''

5、贪婪和非贪婪
正则表达式都是贪婪的,能多匹配就多匹配
.*? 取消贪婪
.+? 取消贪婪
见提取a链接的href和内容

#贪婪 非贪婪
import re
pattern = re.compile(r'<div>.*</div>')    # .*是贪婪的 多占
#pattern = re.compile(r'<div>.*?</div>') #.*?取消贪婪
#pattern = re.compile(r'<div>.+?</div>')  #.+? 取消贪婪
string = 'hehe<div>怒发冲冠凭栏处,潇潇雨歇抬望眼</div></div>haha'
ret = pattern.search(string)
print(ret.group())   

#以上代码输出的结果为 <div>怒发冲冠凭栏处,潇潇雨歇抬望眼</div></div>
#如何用子模式()来取自己想要部分  怒发冲冠凭栏处,潇潇雨歇抬望眼
#用()把想要的部分弄成子模式通过print(ret.group(1))来取
import re
#pattern = re.compile(r'<div>(.*)</div>')   
pattern = re.compile(r'<div>(.*?)</div>')   
#pattern = re.compile(r'<div>(.+?)</div>')  
string = 'hehe<div>怒发冲冠凭栏处,潇潇雨歇抬望眼</div></div>haha'
ret = pattern.search(string)
#print(ret.group())  
print(ret.group(1))  


#取出链接的网址和标题
#http://www.baidu.com/cache/sethelp/help.html
#把百度设为主页
#先通过正则和网址一一对应,再把想取出的用()变成子模式用print(ret.group(1))取出
import re
pattern = re.compile(r'<a id="self" href="(.*?)".*?>(.*?)</a>')
string = '''<a id="self" href="http://www.baidu.com/cache/sethelp/help.html" onmousedown="return ns_c({'fm':'behs','tab':'favorites','pos':0})" target="_blank">把百度设为主页</a>'''
ret = pattern.search(string)
print(ret.group())
print(ret.group(1))
print(ret.group(2))

6、模式修正 (对正则表达式进行一些功能的修正和补充)
re.I 忽略大小写的匹配
re.S single 视为单行模式,点可以匹配换行
re.M 视为多行模式,每一行都是一个字符串

""":
import re
pattern = re.compile(r'love')
string = 'i love you xueer'
ret = pattern.findall(string)
print(ret) 

#re.I让正则忽略大小写匹配

import re
pattern = re.compile(r'love',re.I)
string = 'i LOVE you xueer'
ret = pattern.findall(string)
print(ret) 

#re.S让正则忽略换行匹配

#本来.不能匹配换行符但re.S视为单行模式.可以匹配换行符
import re
pattern = re.compile(r'xueer.ha', re.S)
string = 'i love you xueer\nhaha'  #\n 换行符
ret = pattern.search(string)
print(ret.group())


#re.M 视为多行模式每一行都是一个字符串
import re 
pattern = re.compile(r'^i', re.M )
string = ''' I LOVE you xueer haha
i hate you
i like you
'''
ret = pattern.findall(string)
print(ret)

#混用 re.M | re.I  多行模式或忽略大小写

import re 
pattern = re.compile(r'^love', re.M | re.I)
string = '''LOVE you xueer haha
Love hate you
LOVE like you
'''
ret = pattern.findall(string)
print(ret)

"""

7、sub、split
正则切割split 按照正则匹配到的字符串进行切割
正则替换sub 替换正则匹配到的内容

'''
# 正则切割
import re
pattern = re.compile(r'\d')
string = '我今年8岁了,我有5毛钱,我喜欢隔壁3岁的妹妹'
lt = pattern.split(string)
print(lt)

#正则匹配的字符串'8''5''3'  split按照正则匹配到的字符串进行切割
#['我今年', '岁了,我有', '毛钱,我喜欢隔壁', '岁的妹妹']

# 正则替换
#以前
#字符串替换只能替换18 只能将18替换成118
import re
pattern = re.compile(r'\d+')
string = '我喜欢隔壁18岁的美女'
string1 = string.replace('18', '118')  
print(string1)

#现在
#正则替换:字符替换不论18 19....都可以替换 pattern.sub('118', string)
import re
pattern = re.compile(r'\d+')
string = '我喜欢隔壁18岁的美女'
string1 = pattern.sub('118', string)
print(string1)

'''
#子模式正则替换
#替换成数值+1


import re 

def func(ret):
    #ret就是正则替换的对象
    #print(ret)
    #提取正则替换内容将其转化成整形
    sui = int(ret.group())
    #内容+1
    sui+=1
    #返回指定的字符串
    return str(sui)

pattern = re.compile(r'\d+')
string = '我喜欢隔壁18岁的美女'

# 该正则替换:替换的就是func函数的返回值
string1 = pattern.sub(func, string)
print(string1)
#流程
#调用sub的时候会用(func)替换(正则替换的内容)
#会调用func函数print (ret)即要替换的内容会传递给ret

练习
写正则,匹配qq号码(5-12),没有以0开头的
匹配手机号码(11) 第一位和第二位稍微限制下

1、写出正则,匹配前面三个正确的邮箱格式
[email protected]
[email protected]
[email protected]
[email protected]

2、写出正则,匹配正确的手机号
3、写出正则,匹配后五位相同的手机号
13567891010
12345678900 错误
15790908888
17930212345
19901011111
18822366666
01010101010 错误
09456781356 错误

4、写出正则,匹配如下url
http://www.baidu.com
http://www.163.com/index.html
https://www.sina.cn:8080/index.html?username=goudan
https://www.haha.net/index.html?username=goudan&passwor=1234

猜你喜欢

转载自blog.csdn.net/weixin_41853490/article/details/81027526
今日推荐