re模块下的常用方法
import re
ret = re.findall('\d+(\.\d+)?', '1.23+2.34')
print(ret) 结果: ['.23','.34']
# findall的正则表达式里面有分组(),()里面的内容优先显示
ret = re.findall('\d+(?:\.\d+)?', '1.23+2.34')
print(ret) 结果: ['1.23','2.34']
# ?:写在一个分组的最开始,表示在findall方法中取消这个分组的优先级
ret = re.findall('a', 'eva egon yuan') # 返回所有满足匹配条件的结果,放在列表里
print(ret) #结果 : ['a', 'a']
ret = re.search('a', 'eva egon yuan').group()
print(ret) #结果 : 'a' # 函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以
# 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
ret = re.match('a', 'abc').group() # 同search,不过是在字符串开始处进行匹配,默认加'^',没有返回None
print(ret) #结果 : 'a'
ret = re.split('[ab]', 'abcd')
# 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割 print(ret) # ['', '', 'cd']
ret = re.split('\d+','alex123wusir456')
print(ret) #['alex','wusir','']
ret = re.split('(\d+)','alex123wusir456')
print(ret) #['alex','123','wusir','456','']
# split中如果带有分组(),会在分割的同时保留被分割内容中带分组的部分
ret = re.sub('\d', 'H', 'eva3egon4yuan4', 1) #将数字替换成'H',参数1表示只替换1个
print(ret) # evaHegon4yuan4
ret = re.subn('\d', 'H', 'eva3egon4yuan4') #将数字替换成'H',返回元组(替换的结果,替换了多少次)
print(ret) #('evaHegonHyuanH',3)
obj = re.compile('\d{3}') # 将正则表达式编译成为一个正则表达式对象,规则要匹配的是3个数字 ret = obj.search('abc123eeee') # 正则表达式对象调用search,参数为待匹配的字符串 print(ret.group()) #结果 : 123import re ret = re.finditer('\d', 'ds3sy4784a') #finditer返回一个存放匹配结果的迭代器 print(ret) # <callable_iterator object at 0x10195f940> print(next(ret).group()) #查看第一个结果 ret.__next__ == next(ret) print(next(ret).group()) #查看第二个结果 print([i.group() for i in ret]) #查看剩余的左右结果 3 4 7 8 4
综合练习与扩展
1、匹配标签
import reret = re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>") #还可以在分组中利用?P<name>的形式给分组起名字 #获取的匹配结果可以直接用group('名字')拿到对应的值 print(ret.group('tag_name')) #结果 :h1 print(ret.group()) #结果 :<h1>hello</h1> ret = re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>") #如果不给组起名字,也可以用\序号来找到对应的组,表示要找的内容和前面的组内容一致 #获取的匹配结果可以直接用group(序号)拿到对应的值 print(ret.group(1)) # 结果:h1 print(ret.group()) #结果 :<h1>hello</h1>
2、匹配整数
import reret=re.findall(r"\d+","1-2*(60+(-40.35/5)-(-4*3))") print(ret) #['1', '2', '60', '40', '35', '5', '4', '3'] ret=re.findall(r"-?\d+\.\d+|(-?\d+)","1-2*(60+(-40.35/5)-(-4*3))") print(ret) #['1', '-2', '60', '', '5', '-4', '3'] ret.remove("") print(ret) #['1', '-2', '60', '5', '-4', '3']
3、数字匹配
1、 匹配一段文本中的每行的邮箱http://blog.csdn.net/make164492212/article/details/516566382、 匹配一段文本中的每行的时间字符串,比如:‘1990-07-12’;分别取出1年的12个月(^(0?[1-9]|1[0-2])$)、一个月的31天:^((0?[1-9])|((1|2)[0-9])|30|31)$3、 匹配qq号。(腾讯QQ号从10000开始) [1,9][0,9]{4,}4、 匹配一个浮点数。 ^(-?\d+)(\.\d+)?$ 或者 -?\d+\.?\d*5、 匹配汉字。 ^[\u4e00-\u9fa5]{0,}$ 6、 匹配出所有整数
4、爬虫练习
import re import json from urllib.request import urlopendef getPage(url):response = urlopen(url)return response.read().decode('utf-8')def parsePage(s):com = re.compile('<div class="item">.*?<div class="pic">.*?<em .*?>(?P<id>\d+).*?<span class="title">(?P<title>.*?)</span>''.*?<span class="rating_num" .*?>(?P<rating_num>.*?)</span>.*?<span>(?P<comment_num>.*?)评价</span>', re.S)ret = com.finditer(s)for i in ret:yield {"id": i.group("id"),"title": i.group("title"),"rating_num": i.group("rating_num"),"comment_num": i.group("comment_num"),}def main(num):url = 'https://movie.douban.com/top250?start=%s&filter=' % numresponse_html = getPage(url)ret = parsePage(response_html)print(ret)f = open("move_info7", "a", encoding="utf8")for obj in ret:print(obj)data = str(obj)f.write(data + "\n")count = 0 for i in range(10):main(count)count += 25
flags有很多可选值:re.I(IGNORECASE)忽略大小写,括号内是完整的写法 re.M(MULTILINE)多行模式,改变^和$的行为 re.S(DOTALL)点可以匹配任意字符,包括换行符 re.L(LOCALE)做本地化识别的匹配,表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境,不推荐使用 re.U(UNICODE) 使用\w \W \s \S \d \D使用取决于unicode定义的字符属性。在python3中默认使用该flag re.X(VERBOSE)冗长模式,该模式下pattern字符串可以是多行的,忽略空白字符,并可以添加注释
# 正则表达式# 元字符# 量词# 小规则# 贪婪和惰性匹配# 分组命名# 如果在匹配的时候遇到了没有特点的内容,# 只能通过匹配不想要的内容来从中摘取想要的内容# findall和split的分组优先# flags参数# 每一小段规则的元素的排放顺序# re模块# 基础匹配# 分割和替换# 代码优化
# 模块 **** # 什么是模块? # py文件 # c语言编译之后的文件 # 写好的代码集合 直接调用它的功能 # import time # time.sleep()# 为什么要有模块? # 内存空间是有限的,存放在硬盘里,当你需要的时候加载到我的内存 # 把丰富的功能封装在一个文件里,等用的时候直接导入内存就可以使用# 有哪些种类的模块? # 内置模块 # 扩展模块# django# 安装 : pip3 install 模块名 # 自定义模块# 登录# 写日志# 分模块: 功能独立\防止代码过长