Python3编写网络爬虫03-正则表达式的使用
一、正则表达式(处理字符串强大的工具,有特定的语法结构)
功能:实现字符串的检索,替换,匹配验证
实例:
地址:http://tool.oschina.net/regex/
#测试文本
Hello,my phone number is 010-86432100 and email is pindao@xiaomi.com,and my website is http://xiaomi.com
二、常用匹配方法
1. match() 从字符串起始位置匹配正则表达式,如果匹配,就返回匹配成功结果如果不匹配,就返回None。
参数1 正则表达式 参数2 要匹配的字符串
import re content = 'Hello 123 4567 World_This is a Regex Demo' print(len(content)) result = re.match('^Hellosdddsd{4}sw{10}',content) print(result) print(result.group())#输出匹配的内容 print(result.span())#输出匹配的范围
1.1 匹配目标 从字符串中提取一部分内容 可以使用()
import re content = 'Hello 123 4567 World_This is a Regex Demo' result = re.match('^Hellos(d+)s(d+)sWorld',content) print(result) print(result.group()) print(result.group(1)) print(result.group(2)) print(result.span())
1.2 通用匹配 . 匹配任意字符 除换行符 * 匹配前面的字符无限次
改写正则表达式
import re content = 'Hello 123 4567 World_This is a Regex Demo' result = re.match('^Hello.*Demo$',content) print(result) print(result.group())
1.3 贪婪与非贪婪
import re content = 'Hello 1234567 World_This is a Regex Demo' result = re.match('^He.*(d+).*Demo$',content) print(result) print(result.group(1))
贪婪匹配下,.* 会尽可能多的匹配字符
使用.*? 拒绝贪婪模式 尽可能少匹配字符
import re content = 'Hello 1234567 World_This is a Regex Demo' result = re.match('^He.*?(d+).*Demo$',content) print(result) print(result.group(1))
注意: 如果匹配结果在字符串结尾 .*? 就有可能匹配不到任何内容了
import re content = 'http://www.baidu.com/serch/kERacN' result1 = re.match('http.*?serch/(.*?)',content) result2 = re.match('http.*?serch/(.*)',content) print(result1.group(1)) print(result2.group(1))
1.4 修饰符
import re content = '''Hello 1234567 World_This is a Regex Demo''' result = re.match('^He.*?(d+).*?Demo$',content) print(result.group(1))
. 匹配换行符之外的任意字符 添加修饰符 re.S (使.匹配包括换行符在内的所有字符)
import re content = '''Hello 1234567 World_This is a Regex Demo''' result = re.match('^He.*?(d+).*?Demo$',content,re.S) print(result.group(1))
re.I 使匹配对大小写不敏感
re.L 做本地化识别(locale-aware)匹配
re.M 多行匹配 ,影响^和$
re.S 使.匹配包括换行符在内的所有字符
re.U 根据Unicode字符集解析字符 影响 w W B
网页匹配 常用 re.S re.L
1.5 转义匹配
.匹配除换行符以外的任意字符 如果目标字符串里面包含.
import re content = '(百度)www.baidu.com' result = re.match('(百度)www.baidu.com',content) print(result)
遇到正则匹配模式的特殊字符 在前面加反斜杠转义
2. search() 匹配整个字符串 返回第一个成功匹配的结果 匹配失败 返回None
import re content = 'Auto Hello 1234567 World_This is a Regex Demo' result = re.match('He.*?(d+).*Demo',content) print(result)#返回None import re content = 'Auto Hello 1234567 World_This is a Regex Demo' result = re.search('He.*?(d+).*Demo',content) print(result)
实例:
利用search方法 提取 html文档中 齐秦 往事随风
查看文件 html.txt
import re html = '''<div > <h2 class="title">经典老歌</h2> <p class="introduction"> 经典老歌列表 </p> <ul > <li data-view="2">一路上有你</li> <li data-view="7"> <a href="/2.mp3" singer="任贤齐">沧海一声笑</a> </li> <li data-view="4" class="active"> <a href="/3.mp3" singer="齐秦">往事随风</a> </li> <li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li> <li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li> <li data-view="5"> <a href="/6.mp3" singer="邓丽君">但愿人长久</a> </li> </ul> </div>''' result = re.search('li.*?active.*?singer="(.*?)">(.*?)</a>',html,re.S) print(result) print(result.group(1)) print(result.group(2))
3.findall() 搜索整个字符串 返回匹配规则的所有内容
实例:
3.1利用 findall方法 提取所有a节点的超链接 歌手 歌名
result = re.findall('li.*?href="(.*?)".*?singer="(.*?)">(.*?)</a>',html,re.S) print(result)
3.2遍历 依次获取每组内容
for results in result: print(results)
3.2对应索引依次取出
for results in result: print(results[0],results[1],results[2])
4.sub() 参数1 规则 参数2 规则 参数3 字符串
strs = '34iaU8hw9kcj2k3O0jc7oqqw8W'
去掉所有数字
import re strs = '34iaU8hw9kcj2k3O0jc7oqqw8W' strs = re.sub('d+','',strs) print(strs)
获取html文本 所有li节点的歌名
results = re.findall('<li.*?>s*?(<a.*?>)?(w+)(</a>)?s*?</li>',html,re.S) for result in results: print(result[1])
利用sub方法 去掉a节点 再用findall方法提取
html = re.sub('<a.*?>|</a>','',html) # print(html) results = re.findall('<li.*?>(.*?)</li>',html,re.S) # print(results) for result in results: print(result.strip())#去掉字符串两边的空格或者换行符
5.compile() 将正则字符串编译成正则表达式对象 以便复用 也可以传入修饰符 例如re.S 相当于做了一层封装
示例
import re str1 = '2016-12-25 12:00' str2 = '2017-12-17 11:55' str3 = '2018-12-23 15:00' pattern = re.compile('d{2}:d{2}') result1 = re.sub(pattern,'',str1) result2 = re.sub(pattern,'',str2) result3 = re.sub(pattern,'',str3) print(result1,result2,result3)
附正则匹配规则
模式 w 匹配字母、数字、下划线 W 匹配非字母、数字、下划线 s 匹配任意空白字符,等价于[ f] S 匹配任意非空字符 d 匹配任意数字,等价于[0-9] D 匹配任意非数字的字符 A 匹配字符串开头 匹配字符串结尾,如果存在换行,只匹配到换行前的结束字符串 z 匹配字符串结尾,如果存在换行,同时还会匹配换行符 G 匹配最后匹配完成的位置 匹配一个换行符 匹配一个制表符 ^ 匹配一行字符串的开头 $ 匹配一行字符串的结尾 . 匹配任意字符,除换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符串 [...] 用来表示一组字符,单独列出 例如[amk] 匹配a,m或k [^...] 不再[]中的字符 例如[^abc] 匹配除了a,b,c之外的字符 * 匹配0个或多个表达式 + 匹配1个或多个表达式 ? 匹配0个或1个前面的表达式定义的片段,非贪婪模式 {n} 精确匹配n个前面的表达式 {n,m} 匹配n到m次由前面表达式定义的片段,贪婪模式 a|b 匹配a或b ( ) 匹配括号内的表达式,也表示一个组