1. 程式人生 > >二十一、正則表達式(re模塊)

二十一、正則表達式(re模塊)

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模塊)