正则
正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配,提供了一种字符串的匹配模式(pattern)
常用的元字符
1. [] # 包含,默认是一个字符长度
[a] # 匹配a字母
[abc] # 匹配a或b或c中的任意一个
[a-z] # 匹配a-z中的任意一个
[A-Z] # 匹配A-Z中的任意一个
[a-zA-Z] # 匹配任意一个字母
[0-9] # 匹配数字
2. ^ 以..开头
^a # 匹配以a作为开头的一串字符
^abc # 匹配以abc作为开头的一串字符
^[abc] # 匹配a或b或c开头的一串字符
[^abc] # 匹配除去a或b或c以外的
[^a-zA-Z] # 匹配a-z或A-Z以外的字符
3. $ 以..结尾
^[1][3-8][0-9]{9}$ # 匹配手机号, 以1作为开头 第二位是3-8, 后几位是0-9
^[1][345678][0-9]{9}$ # 匹配手机号, 同上
4. {m} 表示匹配前面表达式m次
abc{2} # 匹配ab和c两次
1[a-z]{2} # 匹配1和两个小写字母
5. {m,n} 表示匹配前面的表达从m到n次
[1-9][0-9]{4,10} # 匹配第一位是1-9, 4到10位的数字0-9
6. {m,} 匹配前面的表达式至少m次
7. ? 表示前面的表达式可有可无
[1-9][0-9]? # 匹配数字1-99(后面的一位0-9可有可无)
8. . 匹配除了换行符\n以外的任意字符
.{2} # 匹配除了换行符以外的任意两个字符。
9. * 匹配起那么的表达式 0次到多次
.* # 匹配除了换行符以外的任意字符任意次--贪婪模式
.{0,} # 同上
.*? # 匹配除了换行符以外的任意字符任意次--拒绝贪婪模式
10. + 表示匹配前面的表达式1次到多次
.+ # 匹配除了换行符以外的任意字符至少一次-- 贪婪模式
.{1,} # 同上
.+? # 匹配除了换行符以外的任意字符至少一次--拒绝贪婪模式
11. () # 代表一个临时区域单元, 表达式定义为组;2.匹配括号内容并获取这一匹配。
12. | 或
a|b # 匹配a或b
ab(c|d) # 匹配ab与c或d其中一个
正则在python中的修正符
re.I # 匹配不区分大小写, 还可以使用全称的re.IGNORECASE。
re.M # 将要匹配的字符串视为多行,可以匹配每一行, 还可以使用全称的re.MULTILINE
re.S # 将要匹配的字符串视为单行,并把换行符作为一个普通字符匹配,还可以使用全称的re.DOTALL
# 可以使用或运算符|同时设置多个修正符。
特殊意义的字符
\d 等同于[0-9] # 匹配一位数字
\D 等同于[^0-9] # 匹配除了数字以外的一个字符
\w 等同于[a-zA-Z0-9_ ] # 匹配数字字母下划线的一个字符
\W 等同于[^a-zA-Z0-9_ ] # 匹配除了字母数字下划线的其他字符
\s 等同于[\n\r\t] # 匹配空白字符 包括空格、制表符、换页符等等
\S # 匹配非空白字符
正则常用的函数
导入模块
import re
(1) re.findall(pattern, string, flags)
匹配所有内容,李列表的形式返回, 当匹配失败时候返回空列表
参数1:正则的匹配规则
参数2:要匹配的字符串
参数3:修正符
实例:
myStr = """
<a href="http://www.baidu.com">百*</a> # 给每一行进行编号1
<a href="http://www.taobao.com">淘*1</a> # 2
<a href="www.taobao.com">淘*2</a> # 3
<A href="http://www.id97.com">电影网站</> # 4
<a href="http://www.jd.com">*东 # 5
</a>
"""
dataList = re.findall('<a href=".*?">.*?</a>',myStr) # 匹配1,2,3. 返回列表
dataList = re.findall('<a href=".*?">.*?</a>', myStr, re.I) # 匹配编号1234,不区分大小写
dataList = re.findall('<a href=".*?">.*?</a>',myStr,re.S|re.I) # 匹配12345
print(dataList)
(2) re.match(pattern, string, flags)
从开始位置匹配,只匹配一次, 匹配成功返回对象,匹配失败返回None
参数同上
实例:
ret = re.match("[a]","1a")
print(ret) # None 从开始第一个位置处匹配
ret = re.match("[a-zA-Z]{2,3}","Aaaaaa")
print(ret) # 返回对象 <_sre.SRE_Match object; span=(0, 3), match='Aaa'>, 匹配了三次
# 使用返回的对象的group()方法获取匹配的结果
print(ret.group()) # Aaa
(3) re.search(pattern, string, flags)
匹配一次, 匹配成功返回匹配的对象,匹配失败返回None。与re.match()
区别是就是可以从任意位置匹配。
实例:
ret = re.search("[a]","1a")
print(ret) # 从开始第二个位置处匹配 <_sre.SRE_Match object; span=(1, 2), match='a'>
print(ret.group()) # 打印 a
(4) re.sub(pattern, repl,count, flags)/re.subn()
使用正则表达式替换, 返回替换后的结果
re.subn()可以返回替换后的结果和次数
实例:
myStr = "<b>我是b</b><i>我是i</i><strong>我是strong</strong>"
# 将b换成em 即<em>第三方</em>
data = re.sub("<b>(.*?)</b>", "<em>我是em</em>", myStr)
print(data) # <em>我是em</em><i>我是i</i><strong>我是strong</strong>
# 将所有的标签名换成em,不改变标签内的内容
data = re.sub("<b>(.*?)</b><i>(.*?)</i><strong>(.*?)</strong>", "<em>\\1</em><em>\\2</em><em>\\3</em>",myStr)
print(data) # 其中\1是取第一个(.*?)获取的内容, \2是第二个(.*?)的内容,...。<em>我是b</em><em>我是i</em><em>加粗strong</em>
# 将1970/01/02变为01月02日1970年(考察分组,内容的获取)
myData = "1970/01/02"
ret = re.sub("(\d+)/(\d+)/(\d+)", "\\2月\\3日\\1年", myData)
print(ret) # 01月02日1970年
(5)re.split(pattern,string,maxsplit,flags)
正则的拆分, 将字符串拆分成列表
参数:
maxsplit: 最大的拆分次数
实例:
data = "1jjj1h$hhh1hjj&j1"
print(re.split("\W",data)) # ['1jjj1h', 'hhh1hjj', 'j1'] ---使用除了字母数字下划线以外的字母进行拆分
print(re.split("\d",data)) # ['', 'jjj', 'h$hhh', 'hjj&j', ''] ---使用一位数字进行拆分
print(re.split("\d",data,1)) # ['', 'jjj1h$hhh1hjj&j1'] ---使用一位数字进行拆分,拆分一次
(6)re.finditer(pattern,string,maxsplit,flags)
匹配所有, 以迭代器的形式返回结果
实例:
myStr = "abcDMdefg23456uuii"
reIter = re.finditer("[a-z]",myStr) # 匹配的结果应该是abcdefguuii, 但是使用迭代器返回了
print(reIter) # <callable_iterator object at 0x...>
print(next(reIter)) # 调用next()输出 <_sre.SRE_Match object; span=(0, 1), match='a'>
print(next(reIter).group()) # a ---进行取值
(7) re.compile(pattern, flags)
先使用compile()函数, 将正则表达式编译为Pattern实例, 然后使用Pattern实例处理文本并获得匹配结果, 执行效率高 将正则和字符串分开
实例:
myStr = "abcDMdefg23456uuii"
pattern = re.compile("[a-z]")
ret = pattern.findall(myStr) # 其他的方法(match,sub..)都可以使用
print(ret) # ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'u', 'u', 'i', 'i']
URL处理模块
导包
import urllib.request
(1) urlopen(url, timeout) 打开连接地址
timeout: 设置超时时间
实例:
import urllib.request
url = "http://bbs.tianya.cn/m/post-140-393974-6.shtml"
response = urllib.request.urlopen(url,)
print(response) # HTTPResponse object
print(response.read()) # 打印响应的内容,但是返回的是字节形式的内容,需要根据网页head设置的编码进行解码
print(response.read().decode('utf-8'))
print(response.readlines()) # 读取每一行 以列表的形式返回
print(response.code) # 返回状态码
print(response.geturl()) # 获取当前访问的地址
(2) url地址编码
实例:
url = " https://www.baidu.com/s?word=美女&tn=site888_3_pg&lm=-1&ssl_s=1&ssl_c=ssl1_160e40bb10d"
ret = urllib.request.quote(url)
print(ret) # 对url地址进行url编码 https%3A//www.baidu.com/s%3Fword%3D%E7%BE%8E%E5%A5%B3%26tn%3Dsite888_3_pg%26lm%3D-1%26ssl_s%3D1%26ssl_c%3Dssl1_160e40bb10d
print(urllib.request.unquote(ret)) # 进行url解码 https://www.baidu.com/s?word=美女&tn=site888_3_pg&lm=-1&ssl_s=1&ssl_c=ssl1_160e40bb10d
(3) 添加用户代理UserAgent(在后面爬虫部分很有用)
查看你当前浏览器的ua:
实例:
import urllib.request
url = "http://www.baidu.com"
ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv2.0.1) Gecko/20100101 Firefox/4.0.1"
request = urllib.request.Request(url,headers={'User-Agent':ua}) # 实例化request对象
response = urllib.request.urlopen(request )
print(response.read().decode("utf-8"))
(4) 下载文件
request.urlretrieve(url, fileName)
参数:
url: 下载的url地址
fileName:保存到本地的文件名
实例:
from urllib import request
url = "http://www.sinaimg.cn/dy/slidenews/4_img/2009_44/163_13716_315914.jpg"
request.urlretrieve(url, "1.jpg")