python学习day18 常用模块:re
正则测试:http://tool.chinaz.com/regex/
谈到正则,就只和字符串相关了
参考:http://www.cnblogs.com/Eva-J/articles/7228075.html#_label10
几个常用的非贪婪匹配:
*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复
.*?x 取尽量少的任意字符,直到x出现
python中的正则:
import re
findall
search
match
ret = re.findall('[a-z]+', 'eva egon yuan') # 返回所有满足匹配条件的结果,放在列表里 print(ret) ret = re.search('a', 'eva egon yuan') if ret: print(ret.group()) # 从前往后,找到一个就返回,返回的变量需要调用group才能拿到结果 # 如果没有找到,那么返回None,调用group会报错 # ret = re.match('[a-z]+', 'eva egon yuan') if ret: print(ret.group()) # match是从头开始匹配,如果正则规则从头开始可以匹配上,就返回一个变量。 # 匹配的内容需要用group才能显示 # 如果没匹配上,就返回None,调用group会报错
其他功能:
ret = re.split('[ab]', 'abcd') # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割 print(ret) # ['', '', 'cd'] 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()) # 123 ret = obj.search('abcashgjgsdghkash456eeee3wr2') #正则表达式对象调用search,参数为待匹配的字符串 print(ret.group()) #结果 : 456
import re ret = re.finditer('\d', 'ds3sy4784a') #finditer返回一个存放匹配结果的迭代器 print(ret) # <callable_iterator object at 0x10195f940> # print(next(ret).group()) #查看第一个结果 # print(next(ret).group()) #查看第二个结果 # print([i.group() for i in ret]) #查看剩余的左右结果 for i in ret: print(i.group())
两个特殊的点:
1.findall的优先级查询
import re 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.split的优先级查询
ret=re.split("\d+","eva3egon4yuan") print(ret) #结果 : ['eva', 'egon', 'yuan'] ret=re.split("(\d+)","eva3egon4yuan") print(ret) #结果 : ['eva', '3', 'egon', '4', 'yuan'] #在匹配部分加上()之后所切出的结果是不同的, #没有()的没有保留所匹配的项,但是有()的却能够保留了匹配的项, #这个在某些需要保留匹配部分的使用过程是非常重要的。
一段简单的爬虫代码:
爬取豆瓣前250影片的信息:
import re from urllib.request import urlopen def getPage(url): response = urlopen(url) return response.read().decode('utf-8') def parsePage(s): ret = re.findall( '<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>',s,re.S) return ret def main(num): url = 'https://movie.douban.com/top250?start=%s&filter=' % num response_html = getPage(url) ret = parsePage(response_html) print(ret) count = 0 for i in range(10): # 10页 main(count) count += 25
flag:
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字符串可以是多行的,忽略空白字符,并可以添加注释