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) # <callable_iterator object at 0x00000278077385C0>
print(next(ret).group()) # 65565765
print(next(ret).group()) # 767
三.综合练习与扩展
1.匹配标签
(1).普通版
ret = re.search("<\w+>\w+</\w+>","<h1>hello</h>")
print(ret.group()) # <h1>hello</h1>
(2).分组命名版
还可以在分组中利用?P<name>的形式给分组起名字,获取的匹配结果可以直接用group('名字')拿到对应的值
ret = re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>")
?P<tag_name> 起名字 ?P=tag_name 使用分组名字
print(ret.group("tag_name")) # h1
print(ret.group()) # <h1>hello</h1>
(3)分组索引 从1开始
如果不给组起名字,也可以用"\序号"来找到对应的组,表示要找的内容和前面的组内容一致
获取的匹配结果可以直接用group(序号)拿到对应的值
ret = re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>")
print(ret.group()) #<h1>hello</h1>
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('<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='%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
转载于:https://www.cnblogs.com/J-7-H-2-F-7/p/9306817.html