二十一、正則表達式(re模塊)
阿新 • • 發佈:2017-11-29
ons brush 內容 page 返回對象 req 規則 www. 叠代
re模塊
正則表達式:
字符串模糊匹配
字符(普通字符、元字符)
普通字符:普通字母,字符
完全匹配
import re print(re.findall(‘chen‘,‘shuaigeshichen‘)) # ‘chen‘
元字符:$. ^ * + ? { } [ ] | ( ) \
模糊匹配
re常用方法:
# findall() 匹配所有符合規則對象(規則,匹配項),返回一個列表 # search() 只匹配一項,成功返回對象,失敗返回None,通過對象.group取值(規則,匹配項) # match() 只匹配字符串開始位置,成功返回對象,失敗返回None,通過對象.group取值(規則,匹配項) # split() 切分匹配項,(規則,匹配項,最大分割次數)想要保留分隔符的話就加分組() # sub() 匹配替換(規則:也就是要替換的內容,新的內容,原始內容) # subn() 也是替換,以元組形式返回,並且返回替換的次數 # compile() 編譯: 先編譯規則,拿到對象:obj = re.compile("\w+") 這樣規則就給了obj, obj.findall("內容")就可以直接匹配 # finditer() 返回一個叠代器對象;如果匹配項特別大,推薦使用這個方法,一個個拿
單個字符匹配:
. 匹配除換行符以外的任意一個字符
print(re.findall(‘陳.‘,‘陳一,陳二,李三,陳六七‘)) # [‘陳一‘, ‘陳二‘, ‘陳六‘] print(re.findall(‘陳..‘,‘陳一,陳二,李三,陳六七‘)) # [‘陳一,‘, ‘陳二,‘, ‘陳六七‘]
^ 匹配字符串的開頭部分
print(re.findall(‘^陳.‘,‘陳一,陳二,李三,陳六七‘)) # [‘陳一‘] print(re.findall(‘^陳..‘,‘陳一,陳二,李三,陳六七‘)) # [‘陳一,‘]
$ 匹配字符串的結束部分
print(re.findall(‘a..m‘,‘a陳一,a陳二m成,a李三j,a陳六m‘)) # [‘a陳二m‘, ‘a陳六m‘] print(re.findall(‘a..m$‘,‘a陳一,a陳二m,a李三j,a陳六m‘)) # [‘a陳六m‘]
重復匹配:
* 重復0到無窮次
print(re.findall(‘138\d*‘,‘1384561456,1561,138,14561‘)) # [‘1384561456‘, ‘138‘]
+ 重復1到無窮次
print(re.findall(‘138\d+‘,‘1384561456,1561,138,14561‘)) # [‘1384561456‘]
? 重復0到1次
print(re.findall(‘-?\d+‘,‘16,11,-8,61‘)) # [‘16‘, ‘11‘, ‘-8‘, ‘61‘]
{} 重復指定次
print(re.findall(‘\d{2}‘,‘1384561456,1561,138,14561‘)) # [‘13‘, ‘84‘, ‘56‘, ‘14‘, ‘56‘, ‘15‘, ‘61‘, ‘13‘, ‘14‘, ‘56‘]
\轉義符:
1、反斜杠後邊跟元字符去除特殊功能,比如\.
print(re.findall("\.com","baidu.com")) # [‘.com‘] 這裏匹配規則的 . 只是個普通符合
2、反斜杠後邊跟普通字符實現特殊功能,比如\d
\d 匹配任何十進制數; 它相當於 [0-9]。 \D 匹配任何非數字字符; 它相當於 [^0-9]。 \s 匹配任何空白字符; 它相當於 [ \t\n\r\f\v]。 \S 匹配任何非空白字符; 它相當於 [^ \t\n\r\f\v]。 \w 匹配任何字母數字字符; 它相當於 [a-zA-Z0-9_]。 \W 匹配任何非字母數字字符; 它相當於 [^a-zA-Z0-9_] \b 匹配一個特殊字符邊界,比如空格 ,&,#等
\b 規則需要加‘r‘
執行時是python解釋器執行,調用re模塊實現,執行這段代碼,是解釋器翻譯後,交給re模塊的findall處理;
解釋器碰到\b是有意義的(\b在ascill碼中代表響鈴),所以在這就要先轉義,然後就把 \b 交給 re模塊;
或者加 r 表示原生字符串,表示字符串內的字符都是普通字符;
print(re.findall(r"o\b","hello shuai ge")) # [‘o‘]
通過上面,理解下面
print(re.findall(r"o\\s","hello\shuai")) # [‘o\\s‘] print(re.findall("o\\\\s","hello\shuai")) # [‘o\\s‘]
() 分組
把一些內容作為一項
findall用了分組後,會把分組內容取出來(使用 ?: 取消findall功能,把匹配成功內容全部取出來)
比如匹配規則很多,想要的只是其中的幾個,就可以利用分組
print(re.findall(‘(shuai)+‘,‘shuaiaashuaishuaikkl‘)) # [‘shuai‘, ‘shuai‘]
命名分組
使用?P<>來為分組命名
res = re.search(r" birthday:(?P<year>20[01]\d).(?P<month>\d+)"," birthday:2017:12") print(res.group()) # birthday:2017:12 print(res.group("year")) # 2017 print(res.group("month")) # 12
[ ] 字符集
匹配其中一個字符
字符集的元字符沒有特殊意義(除:- \ ^)
res = re.findall(r"a[b*cd]","abf*cgdada*h") print(res) # [‘ab‘, ‘ad‘, ‘a*‘] # - 表示範圍 res = re.findall(r"a[a-zA-Z0-9_]","ad5aQs5f4aTa5r8a_6") print(res) # [‘ad‘, ‘aQ‘, ‘aT‘, ‘a5‘, ‘a_‘] # \ 仍然轉義 res = re.findall(r"a[\d]","ad5aQs5f4aTa5r8a_6") print(res) # [‘a5‘] # ^ 表示非 res = re.findall(r"a[^\d]","ad5aQs5f4aTa5r8a_6") print(res) # [‘ad‘, ‘aQ‘, ‘aT‘, ‘a_‘]
| 管道符
res = re.findall("www.\w+.(?:com|cn)","www.baidu.com,www.cf.cn") print(res) # [‘www.baidu.com‘, ‘www.cf.cn‘]
貪婪匹配:
滿足匹配時,匹配盡可能短的字符串,使用?來表示非貪婪匹配
res = re.findall("123+","12333456789") print(res) # [‘12333‘]
非貪婪匹配:
滿足匹配時,匹配盡可能短的字符串,使用?來表示非貪婪匹配
res = re.findall("123+?","12333456789") print(res) # [‘123‘]
常用貪婪匹配
# *? 重復任意次,但盡可能少重復 # +? 重復1次或更多次,但盡可能少重復 # ?? 重復0次或1次,但盡可能少重復 # {n,m}? 重復n到m次,但盡可能少重復 # {n,}? 重復n次以上,但盡可能少重復 # # . 是任意字符 # * 是取 0 至 無限長度 # ? 是非貪婪模式。 # 何在一起就是 取盡量少的任意字符,一般不會這麽單獨寫,他大多用在: # .*?x # # 就是取前面任意長度的字符,直到一個x出現
利用正則匹配爬蟲
import requests,re def getPage(): respnse_str = requests.get("https://movie.douban.com/top250?start=0&filter=") return respnse_str.text def run(): resonse = getPage() obj = re.compile(‘<div class="item">.*?<em.*?>(?P<id>\d+)</em>.*?<span class="title">(.*?)</span>‘ ‘.*?<span class="rating_num".*?>(.*?)</span>‘, re.S) ret = obj.findall(resonse) print(ret) run()
二十一、正則表達式(re模塊)