30 re模块2 一.正则表达式在线测试 在线测试工具 http://tool.chinaz.com/regex/ (一).*?的用法: . 是任意字符 * 是取 0 至 无限长度 ? 是非贪婪模式。 合在一起就是 取尽量少的任意字符,一般不会这么单独写,他大多用在:.*?x 就是取前面任意长度的字符,直到一个x出现 (二).问号"?"的四种用法 1.量词,重复零次或一次 2.非贪婪匹配(惰性匹配)的象征( .*? ) 3.?: 分组一开始加?:表示取消分组优先. 4.?p: 分组命名 html 标签预言中用到. 二.re模块常用方法 基础查找 1.findall 分组优先级 ret=re.findall(r"(\d+\.?\d+)","123.546") print(ret) print(ret.remove("")) #findall的优先级问题 ret=re.findall('www.(baidu|oldboy).com', 'www.oldboy.com') print(ret) #['oldboy'] 这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可 ret=re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com') print(ret) #['www.oldboy.com'] 注释: 分组一开始加" ?: " 表示取消分组优先级. 2.search (group) 函数会在字符串内查找模式匹配,直到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。 ret=re.search("\d+","4huhi67377") print(ret.group()) # 4 ret=re.search("\d+","4888huhi67377") print(ret.group()) #4888 3.match (group) ret=re.match("\d","4huhi67377") #match 里的正则不管是什么,默认在正则前加" ^ " print(ret.group()) 字符串处理 4.split 分组保留 优先级"正则" "(正则)" ret=re.split("(\d+)","ghgh689jhhkjkj888hjh9777") # 用"\d+"切割字符串 加"(正则)"分组保留. print(ret) #['ghgh', '689', 'jhhkjkj', '888', 'hjh', '9777', ''] ret=re.split("\d+","ghgh689jhhkjkj888hjh9777") print(ret) #['ghgh', 'jhhkjkj', 'hjh', ''] 5.sub 替换 ("正则","替换目标值","字符串",2) ret=re.sub("\d+" ,"男神","alex1000wusir666") print(ret) 结果 alex男神wusir男神 ret=re.sub("\d+" ,"男神","alex1000wusir666",1) print(ret) 结果 alex男神wusir666 6.subn ret=re.subn("\d+" ,"男神","alex1000wusir666") print(ret) 结果 ('alex男神wusir男神', 2) 代码优化 7.compile obj=re.compile("\d{4}") ret=obj.search("676767hghjj787878gjggu") print(ret.group()) #结果 6767 ret=obj.findall("hghjj787878gjggu") print(ret.group()) 结果 6767 ret=obj.match("676767hghjj787878gjggu") print(ret.group()) #6767 8.finditer 迭代功能 ret=re.finditer("\d+","ggjgu65565765hjhjk767") for i in ret: print(i.group()) #65565765 767 <二> print(ret) # print(next(ret).group()) # 65565765 print(next(ret).group()) # 767 三.综合练习与扩展 1.匹配标签 (1).普通版 ret = re.search("<\w+>\w+ "," hello") print(ret.group()) #
hello
(2).分组命名版 还可以在分组中利用?P 的形式给分组起名字,获取的匹配结果可以直接用group('名字')拿到对应的值 ret = re.search("<(?P \w+)>\w+ "," hello
") ?P 起名字 ?P=tag_name 使用分组名字 print(ret.group("tag_name")) # h1 print(ret.group()) # hello
(3)分组索引 从1开始 如果不给组起名字,也可以用"\序号"来找到对应的组,表示要找的内容和前面的组内容一致 获取的匹配结果可以直接用group(序号)拿到对应的值 ret = re.search(r"<(\w+)>\w+ "," hello
") print(ret.group()) # hello
print(ret.group(1)) # h1 2.匹配整数和小数 ret=re.findall(r"-?\d+\.\d+|-?\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'] 只取整数 3.数字匹配 (1). 匹配一段文本中的每行的邮箱 http://blog.csdn.net/make164492212/article/details/51656638 正则表达式 : [\w:\./]{1,} 验证: ret=re.findall("[\w:\./]{1,}","http://blog.csdn.net/make164492212/article/details/51656638") print(ret) # ['http://blog.csdn.net/make164492212/article/details/51656638'] (2).匹配一段文本中的每行的时间字符串,比如:‘1990-07-12’;^[1-9][0-9]{1,}\-[0-1][0-9]\-[0-3][0-9] 分别取出1年的12个月 # (^(0?[1-9]|1[0-2])$) 一个月的31天 # ^((0?[1-9])|((1|2)[0-9])|30|31)$ (3)匹配qq [1-9][0-9]{4,} (4)浮点数 ^(-?\d+)(\.\d+)?$ 四.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字符串可以是多行的,忽略空白字符,并可以添加注释 作业: 实现能计算类似 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式的计算器程序 爬虫练习: import requests import re import json def getPage(url): response=requests.get(url) return response.text def parsePage(s): com=re.compile(' .*?
.*?
(?P \d+).*? (?P.*?)</span>' '.*?(?P .*?) .*?(?P .*?)评价 ',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='%num response_html=getPage(url) ret=parsePage(response_html) print(ret) f=open("move_info7","a",encoding="utf8") for obj in ret: print(obj) data=json.dumps(obj,ensure_ascii=False) f.write(data+"\n") if __name__ == '__main__': count=0 for i in range(10): main(count) count+=25 二>