import re #博客截图 # 数字字母下划线 print(re.findall('w','egon 123 + _ - *')) # 非数字字母下划线 print(re.findall('W','egon 123 + _ - *')) #匹配空白字符 print(re.findall('s','ego n 12 3 + _ - *')) #匹配非空字符 print(re.findall('S','egon 123 + _ - *')) #匹配任意数字 print(re.findall('d','egon 123 + _ - *')) #匹配任意非数字 print(re.findall('D','egon 123 + _ - *')) #只匹配 print(re.findall(' ','ego n 12 3 + _ - *')) #只匹配 print(re.findall(' ','ego n 12 3 + _ - *')) #匹配字符串的开头^ print(re.findall('^e','ego n 12hello 3 + _ - *')) #匹配字符串的结尾$ print(re.findall('o$','ego n 12hello 3 + _ - *')) # . ? + * {m,n} # . 代表任意字符 print(re.findall('a.b','a1b a a-b aaaaab')) # . 不能匹配 要加re.DOTALL print(re.findall('a.b','a b a a-b aaaaab',re.DOTALL)) # ?左边的一个字符出现0次或1次 print(re.findall('ab?','a ab abb abbb a1b')) # *代表左边的一个字符出现0次或者无穷次 print(re.findall('ab*','a ab abb abbb a1b')) # + 代表左边的一个字符出现1次或者无穷次 print(re.findall('ab*','a ab abb abbb a1b')) #{m,n} 代表左边的一个字符出现m次到n次 print(re.findall('ab{0,1}','a ab abb abbb a1b')) print(re.findall('ab{0,}','a ab abb abbb a1b')) print(re.findall('ab{1,}','a ab abb abbb a1b')) print(re.findall('ab{2,4}','a ab abb abbb a1b')) #.* 代表 贪婪匹配 print(re.findall('a.*b','jjhfh12ahhjjbwwwb')) # .*? 非贪婪匹配 找到最近的b就结束 print(re.findall('a.*?b','jjhfh12ahhjjbwwwb')) #.+? 表示匹配任意字符一个或则多个 #.*? 表示匹配任意字符0个或多个 print(re.findall('a.+?b','ab')) # 匹配不到 至少要有一个 print(re.findall('a.*?b','ab')) # 能匹配到 # | 或者 print(re.findall('compan(y|iness)','too many companiness have gone bankrupt,and the next one is my company')) print(re.findall('compan(?:y|iness)','too many companiness have gone bankrupt,and the next one is my company')) # rawstring: print(re.findall(r'a\c','ac a1c abc')) # a\c->ac #[]取中括号内任意字符 print(re.findall('a[a-z]b','axb azb aAb a1b a-b a+b')) print(re.findall('a[A-Z]b','axb azb aAb a1b a-b a+b')) print(re.findall('a[a-zA-Z]b','axb azb aAb a1b a-b a+b')) print(re.findall('a[0-9]b','axb azb aAb a1b a-b a+b')) print(re.findall('a[-+*/]b','axb azb aAb a1b a-b a+b')) # 上尖号 ^ 组内使用为取反的意思 print(re.findall('a[^-+*/]b','axb azb aAb a1b a-b a+b')) #re 模块的其它方法 # re.search # 匹配不到返回None 找到一次就停止 print(re.search('a[*]b','azb axb aAb a1b a-b a+b')) print(re.search('a[0-9]b','azb axb aAb a1b a2b a-b a+b').group()) # re.match # 相当于在search的正则前面加上尖号 匹配不到返回None 找到一次就停止 print(re.match('a[0-9]b','azb axb aAb a1b a2b a-b a+b')) print(re.match('a[0-9]b','a1b axb aAb a1b a2b a-b a+b').group()) print(re.search('^a[0-9]b','a1b axb aAb a1b a2b a-b a+b').group()) # re.split 以正则表达式切分 print(re.split(':','root:x:0:0::/root/bin/bash')) 'root:x:0:0::/root/bin/bash'.split(':') #re.sub 替换 print(re.sub('root','admin','root:x:0:0::/root/bin/bash')) #re.compile 正则复用 obj = re.compile('ad{2}b') print(obj.findall('a12b a123b a1234b abb')) print(obj.search('a12b a123b a1234b abb').group())
1.常用匹配符
'.' 默认匹配除 之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行 '^' 匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a"," abc eee",flags=re.MULTILINE) '$' 匹配字符结尾,或e.search("foo$","bfoo sdfsf",flags=re.MULTILINE).group()也可以 '*' 匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac") 结果为['abb', 'ab', 'a'] '+' 匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb'] '?' 匹配前一个字符1次或0次 '{m}' 匹配前一个字符m次 '{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb'] '|' 匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC' '(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c 'A' 只从字符开头匹配,re.search("Aabc","alexabc") 是匹配不到的 '' 匹配字符结尾,同$ 'd' 匹配数字[0-9] 'D' 匹配非数字 'w' 匹配[A-Za-z0-9] 'W' 匹配非[A-Za-z0-9] 's' 匹配空白字符、 、 、 , re.search("s+","ab c1 3").group() 结果 ' '
2.常用的匹配语法
''' re模块三种比较重要的方法: - findall(): ----> [] 可以匹配 "所有字符" ,拿到返回的结果,返回的结果是一个列表。 'awfwaghowiahioawhio' # a ['a', 'a', 'a', 'a'] - search():----> obj ----> obj.group() 'awfwaghowiahioawhio' # a 在匹配一个字符成功后,拿到结果后结束,不往后匹配。 'a' - match():----> obj ----> obj.group() 'awfwaghowiahioawhio' # a 'a' 'wfwaghowiahioawhio' # a None 从匹配字符的开头匹配,若开头不是想要的内容,则返回None。 '''
re.match 从头开始匹配
re.search 匹配包含
re.findall 把所有匹配到的字符放到以列表中的元素返回
re.splitall 以匹配到的字符当做列表分隔符
re.sub 匹配字符并替换
- ^$: 配合使用叫做精准匹配,如何限制一个字符串的长度或者内容。 - |: 或。ab|abc如果第一个条件成立,则abc不会执行,怎么解决,针对这种情况把长的写在前面就好了,一定要将长的放在前面。 - [^...]: 表示取反的意思。 - [^ab]: 代表只去ab以外的字符。 - [^a-z]: 取a-z以外的字符
3. 实例
import re str1 = 'sean tank Ason' #findall res = re.findall('[a-s]{4}', str1) # 从字符串依次取出4个 print(res) # ['sean', 'tank', 'json'] # search res = re.search('[a-z]{4}', str1) #找到就结束 print(res) print(res.group()) # match res = re.match('sean', str1) print(res) print(res.group()) if res: print(res.group()) 结果: ['sean'] <_sre.SRE_Match object; span=(0, 4), match='sean'> sean <_sre.SRE_Match object; span=(0, 4), match='sean'> sean sean
4.爬虫实例
''' 爬取豆瓣TOP250电影信息 第1页: https://movie.douban.com/top250?start=0&filter= ... 第9页: https://movie.douban.com/top250?start=200&filter= 第10页: https://movie.douban.com/top250?start=225&filter= 爬蟲四部原理: 1.发送请求: requests 2.获取响应数据: 对方机器直接返回的 3.解析并提取想要的数据: re 4.保存提取后的数据: with open() 爬蟲三部曲: 1.发送请求 2.解析数据 3.保存数据 # 往10个链接发送请求获取响应数据 - requests模块 ---》 请求库 ''' import requests import re # 爬蟲三部曲: # 1.发送请求 def get_page(url): response = requests.get(url) # response.content # 获取二进制流数据,比如图片、视频、音频 # response.text # 获取响应文本,比如html代码 return response # 2.解析数据 # 伪代码: # response = get_page('url地址') # parser_page(response.text) def parser_page(text): # response.text # re.findall('正则表达式', '过滤的文本') res_list = re.findall( '<div class="item">.*?<a href="(.*?)">.*?<span class="title">(.*?)</span>.*?<span class="rating_num".*?>(.*?)</span>.*?<span>(.*?)人评价', text, re.S) for movie_tuple in res_list: # print(movie_tuple) yield movie_tuple # 3.保存数据 # 伪代码: # res_list = parser_page(text) # save_data(res_list) def save_data(res_list_iter): with open('douban.txt', 'a', encoding='utf-8') as f: for movie_tuple in res_list_iter: movie_url, movie_name, movie_point, movie_num = movie_tuple # 写入文件前的模样 str1 = f''' 电影地址: {movie_url} 电影名字: {movie_name} 电影评分: {movie_point} 评价人数: {movie_num} ''' f.write(str1) # 获取10个链接 n = 0 for line in range(10): url = f'https://movie.douban.com/top250?start={n}&filter=' n += 25 print(url) response = get_page(url) res_list_iter = parser_page(response.text) # print(res_list_iter) save_data(res_list_iter)
输出结果:
https://movie.douban.com/top250?start=0&filter=
https://movie.douban.com/top250?start=25&filter=
https://movie.douban.com/top250?start=50&filter=
https://movie.douban.com/top250?start=75&filter=
https://movie.douban.com/top250?start=100&filter=
https://movie.douban.com/top250?start=125&filter=
https://movie.douban.com/top250?start=150&filter=
https://movie.douban.com/top250?start=175&filter=
https://movie.douban.com/top250?start=200&filter=
https://movie.douban.com/top250?start=225&filter=