正則
正則表達(dá)式是一個特殊的字符序列抡锈,它能幫助你方便的檢查一個字符串是否與某種模式匹配彼乌,提供了一種字符串的匹配模式(pattern)
常用的元字符
1. [] # 包含,默認(rèn)是一個字符長度
[a] # 匹配a字母
[abc] # 匹配a或b或c中的任意一個
[a-z] # 匹配a-z中的任意一個
[A-Z] # 匹配A-Z中的任意一個
[a-zA-Z] # 匹配任意一個字母
[0-9] # 匹配數(shù)字
2. ^ 以..開頭
^a # 匹配以a作為開頭的一串字符
^abc # 匹配以abc作為開頭的一串字符
^[abc] # 匹配a或b或c開頭的一串字符
[^abc] # 匹配除去a或b或c以外的
[^a-zA-Z] # 匹配a-z或A-Z以外的字符
3. $ 以..結(jié)尾
^[1][3-8][0-9]{9}$ # 匹配手機(jī)號, 以1作為開頭 第二位是3-8, 后幾位是0-9
^[1][345678][0-9]{9}$ # 匹配手機(jī)號, 同上
4. {m} 表示匹配前面表達(dá)式m次
abc{2} # 匹配ab和c兩次
1[a-z]{2} # 匹配1和兩個小寫字母
5. {m,n} 表示匹配前面的表達(dá)從m到n次
[1-9][0-9]{4,10} # 匹配第一位是1-9, 4到10位的數(shù)字0-9
6. {m,} 匹配前面的表達(dá)式至少m次
7. 器紧? 表示前面的表達(dá)式可有可無
[1-9][0-9]? # 匹配數(shù)字1-99(后面的一位0-9可有可無)
8. . 匹配除了換行符\n以外的任意字符
.{2} # 匹配除了換行符以外的任意兩個字符邓尤。
9. * 匹配起那么的表達(dá)式 0次到多次
.* # 匹配除了換行符以外的任意字符任意次--貪婪模式
.{0,} # 同上
.*? # 匹配除了換行符以外的任意字符任意次--拒絕貪婪模式
10. + 表示匹配前面的表達(dá)式1次到多次
.+ # 匹配除了換行符以外的任意字符至少一次-- 貪婪模式
.{1,} # 同上
.+? # 匹配除了換行符以外的任意字符至少一次--拒絕貪婪模式
11. () # 代表一個臨時區(qū)域單元, 表達(dá)式定義為組畔况;2.匹配括號內(nèi)容并獲取這一匹配敦跌。
12. | 或
a|b # 匹配a或b
ab(c|d) # 匹配ab與c或d其中一個
正則在python中的修正符
re.I # 匹配不區(qū)分大小寫, 還可以使用全稱的re.IGNORECASE澄干。
re.M # 將要匹配的字符串視為多行,可以匹配每一行, 還可以使用全稱的re.MULTILINE
re.S # 將要匹配的字符串視為單行,并把換行符作為一個普通字符匹配,還可以使用全稱的re.DOTALL
# 可以使用或運算符|同時設(shè)置多個修正符。
特殊意義的字符
\d 等同于[0-9] # 匹配一位數(shù)字
\D 等同于[^0-9] # 匹配除了數(shù)字以外的一個字符
\w 等同于[a-zA-Z0-9_ ] # 匹配數(shù)字字母下劃線的一個字符
\W 等同于[^a-zA-Z0-9_ ] # 匹配除了字母數(shù)字下劃線的其他字符
\s 等同于[\n\r\t] # 匹配空白字符 包括空格柠傍、制表符麸俘、換頁符等等
\S # 匹配非空白字符
正則常用的函數(shù)
import re
(1) re.findall(pattern, string, flags)
匹配所有內(nèi)容,李列表的形式返回, 當(dāng)匹配失敗時候返回空列表
參數(shù)1pattern:正則的匹配規(guī)則
參數(shù)2string:要匹配的字符串
參數(shù)3flags:修正符
實例
myStr = """
<a >百*</a> # 給每一行進(jìn)行編號1
<a >淘*1</a> # 2
<a href="www.taobao.com">淘*2</a> # 3
<A >電影網(wǎng)站</> # 4
<a >*東 # 5
</a>
"""
dataList = re.findall('<a href=".*?">.*?</a>',myStr) # 匹配1,2,3. 返回列表
#結(jié)果:['<a ,
'<a ,
'<a href="www.taobao.com">淘*2</a>']
dataList = re.findall('<a href=".*?">.*?</a>', myStr, re.I) # 匹配編號123,不區(qū)分大小寫
#結(jié)果:['<a ,
'<a ,
'<a href="www.taobao.com">淘*2</a>']
dataList = re.findall('<a href=".*?">.*?</a>',myStr,re.S|re.I) # 匹配12345
#結(jié)果:['<a ,
'<a ,
'<a href="www.taobao.com">淘*2</a>',
'<A >電影網(wǎng)站</> # 4\n<a >*東 # 5\n</a>']
(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()方法獲取匹配的結(jié)果
print(ret.group()) # Aaa
(3) re.search(pattern, string, flags)
匹配一次, 匹配成功返回匹配的對象,匹配失敗返回None。與re.match()區(qū)別是就是可以從任意位置匹配惧笛。
實例
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()
使用正則表達(dá)式替換, 返回替換后的結(jié)果
re.subn()可以返回替換后的結(jié)果和次數(shù)
實例
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>
# 將所有的標(biāo)簽名換成em,不改變標(biāo)簽內(nèi)的內(nèi)容
data = re.sub("<b>(.*?)</b><i>(.*?)</i><strong>(.*?)</strong>", "<em>\\1</em><em>\\2</em><em>\\3</em>",myStr)
print(data) # 其中\(zhòng)1是取第一個(.*?)獲取的內(nèi)容, \2是第二個(.*?)的內(nèi)容,...从媚。<em>我是b</em><em>我是i</em><em>加粗strong</em>
# 將1970/01/02變?yōu)?1月02日1970年(考察分組,內(nèi)容的獲取)
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)
正則的拆分, 將字符串拆分成列表
參數(shù):
maxsplit: 最大的拆分次數(shù)
實例
data = "1jjj1h$hhh1hjj&j1"
print(re.split("\W",data)) # ['1jjj1h', 'hhh1hjj', 'j1'] ---使用除了字母數(shù)字下劃線以外的字母進(jìn)行拆分
print(re.split("\d",data)) # ['', 'jjj', 'h$hhh', 'hjj&j', ''] ---使用一位數(shù)字進(jìn)行拆分
print(re.split("\d",data,1)) # ['', 'jjj1h$hhh1hjj&j1'] ---使用一位數(shù)字進(jìn)行拆分,拆分一次
(6)re.finditer(pattern,string,maxsplit,flags)
匹配所有, 以迭代器的形式返回結(jié)果
實例
myStr = "abcDMdefg23456uuii"
reIter = re.finditer("[a-z]",myStr) # 匹配的結(jié)果應(yīng)該是abcdefguuii, 但是使用迭代器返回了
print(reIter) # <callable_iterator object at 0x...>
print(next(reIter)) # 調(diào)用next()輸出 <_sre.SRE_Match object; span=(0, 1), match='a'>
print(next(reIter).group()) # a ---進(jìn)行取值
(7) re.compile(pattern, flags)
先使用compile()函數(shù), 將正則表達(dá)式編譯為Pattern實例, 然后使用Pattern實例處理文本并獲得匹配結(jié)果, 執(zhí)行效率高 將正則和字符串分開
實例
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處理模塊
導(dǎo)包
import urllib.request
(1) urlopen(url, timeout) 打開連接地址
timeout: 設(shè)置超時時間
實例:
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()) # 打印響應(yīng)的內(nèi)容,但是返回的是字節(jié)形式的內(nèi)容,需要根據(jù)網(wǎng)頁head設(shè)置的編碼進(jìn)行解碼
print(response.read().decode('utf-8'))
print(response.readlines()) # 讀取每一行 以列表的形式返回
print(response.code) # 返回狀態(tài)碼
print(response.geturl()) # 獲取當(dāng)前訪問的地址
(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地址進(jìn)行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)) # 進(jìn)行url解碼 https://www.baidu.com/s?word=美女&tn=site888_3_pg&lm=-1&ssl_s=1&ssl_c=ssl1_160e40bb10d
(3) 添加用戶代理UserAgent(在后面爬蟲部分很有用)
實例
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)
參數(shù):
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")