前面已經(jīng)初步介紹了正則式的語法規(guī)則和re模塊的方法凄诞。
這次主要舉了幾個(gè)例子思恐,看看re模塊在實(shí)際工作中的使用炮温。
1. re.match
設(shè)定一個(gè)字符串
content = '2005-2018 douban.com, all rights reserved 北京豆網(wǎng)科技有限公司'
- 常規(guī)匹配
result = re.match('2005-\d{4}\s\w{6}\W\w{3}\W{2}\w{3}\s\w{6}\s\w{8}\s.*司$', content)
print(result.group())
輸出結(jié)果
> 2005-2018 douban.com, all rights reserved 北京豆網(wǎng)科技有限公司
- 泛匹配
result = re.match('^2005.*司$', content)
print(result.group())
輸出結(jié)果
> 2005-2018 douban.com, all rights reserved 北京豆網(wǎng)科技有限公司
- 目標(biāo)匹配(括號及group的用法)
content = '2005-2018 douban.com, all rights reserved 北京豆網(wǎng)科技有限公司'
result = re.match('^(\d{4})-(\d{4}).*司$', content)
print(result.group())
print(result.group(1))
print(result.groups(), type(result.groups()))
print(result.group(2))
輸出結(jié)果
> 2005-2018 douban.com, all rights reserved 北京豆網(wǎng)科技有限公司
> 2005
> ('2005', '2018') <class 'tuple'>
> 2018
- re.match從字符串的開頭匹配
(將常規(guī)匹配中表達(dá)式 改成005-\d{4}...
都不能匹配成功) - group與groups的用法:
-
group()
查看正則式所匹配內(nèi)容 -
group(1)
查看正則式中第一個(gè)括號里面的內(nèi)容 -
groups()
將正則式中所有括號里面的內(nèi)容組成一個(gè)tuple横侦,提取字符串要用切片的方法result.groups()[0]
-
group()
里面的參數(shù)是從1開始的彻犁,不是0局待。
-
-
匹配模式的參數(shù)使用 (re.S舉例)
將content內(nèi)容中增加換行符‘\n'
content1 = '2005-2018 douban.com, all rights reserved \n 北京豆網(wǎng)科技有限公司'
使用匹配模式的參數(shù)re.S
斑响,忽略換行符匹配
(具體參數(shù)規(guī)則請查閱上次的內(nèi)容)
result = re.match('^2005.*司$', content1, re.S)
result_error = re.match('^2005.*司$', content1)
print(result.group())
print(result_error)
原本正則式.*
不會匹配換行符,但是填寫參數(shù)re.S
后钳榨,
輸出結(jié)果就能匹配到字符串中的換行符了
> 2005-2018 douban.com, all rights reserved
北京豆網(wǎng)科技有限公司
> None
2. re.search
!!! 為匹配方便舰罚,能用search就不用match !!!
- 貪婪匹配
result1 = re.search('2018.*(\w{6})', content)
print(result1.group(1))
輸出結(jié)果
> 科技有限公司
- 非貪婪匹配
result2 = re.search('2018.*?(\w{6})', content)
print(result2.group(1))
輸出結(jié)果
> douban
區(qū)別:
匹配目標(biāo)(\w{6})
是想截取2018以后的連續(xù)6個(gè)字母數(shù)字及下劃線
貪婪匹配中.*
,盡可能多的匹配到中間的字符薛耻,只剩下最后6個(gè)字符作為匹配目標(biāo)
非貪婪匹配.*?
营罢,卻截取與匹配目標(biāo)最接近的6個(gè)字符
3. re.findall
案例:正則式爬取豆瓣圖書相關(guān)信息
先獲得單個(gè)html源碼
url = 'https://book.douban.com/top250?icn=index-book250-all'
response = requests.get(url)
content = response.text
這里只截取書名和價(jià)格
注意使用非貪婪匹配,否則不能截取所有信息
results = re.findall('title="(\w+)".*?<p class="pl">.*?(\d{2}\.\d{2}).*?</p>', content, re.S)
print(results)
輸出結(jié)果是由tuple組成的list
[('追風(fēng)箏的人', '29.00'), ('小王子', '22.00'), ('圍城', '19.00'), ('解憂雜貨店', '39.50'), ('活著', '12.00'), ('白夜行', '29.80'), ('挪威的森林', '18.80'), ('嫌疑人X的獻(xiàn)身', '28.00'), ('三體', '23.00'), ('不能承受的生命之輕', '23.00'), ('紅樓夢', '59.70'), ('夢里花落知多少', '20.00'), ('看見', '39.80'), ('百年孤獨(dú)', '39.50'), ('何以笙簫默', '15.00'), ('可試讀', '19.50'), ('白夜行', '39.50'), ('三體Ⅱ', '32.00'), ('飄', '40.00'), ('送你一顆子彈', '25.00'), ('三體Ⅲ', '38.00')]
4. re.finditer
和 findall 類似昭卓,在字符串中找到正則表達(dá)式所匹配的所有子串愤钾,并把它們作為一個(gè)迭代器返回
results = re.finditer('title="(\w+)".*?<p class="pl">.*?(\d{2}\.\d{2}).*?</p>', content, re.S)
print(results)
返回一個(gè)迭代器的對象
<callable_iterator object at 0x000001D2FDA98EB8>
要用循環(huán)語句才能調(diào)用:
for result in results:
print(result.groups())
5. re.compile
用于編譯正則表達(dá)式,生成一個(gè)正則表達(dá)式(Pattern)對象候醒,作為參數(shù)供其他re模塊函數(shù)使用
- 以findall改編一下:
pattern = re.compile('title="(\w+)".*?<p class="pl">.*?(\d{2}\.\d{2}).*?</p>', re.S)
results = re.finditer(pattern, content)
6. re.sub
用于替換字符串中的匹配項(xiàng)
- 找出連續(xù)4個(gè)數(shù)字能颁,替換為
hello welcome
content = '2005-2018 douban.com, all rights reserved 北京豆網(wǎng)科技有限公司'
result = re.sub('\d{4}', 'hello welcome', content, 1)
print(result)
輸出結(jié)果為
> hello welcome-2018 douban.com, all rights reserved 北京豆網(wǎng)科技有限公司
- 1表示匹配一次,所以只有2005替換了
- 參數(shù)默認(rèn)為0倒淫,表示符合條件的伙菊,全部替換
- 替換括號內(nèi)的內(nèi)容
result = re.sub('(\d{4})-(\d{4})', r'\2 welcome', content)
print(result)
輸出結(jié)果為:
> 2018 welcome douban.com, all rights reserved 北京豆網(wǎng)科技有限公司
- 按照括號順序,可以將匹配內(nèi)容調(diào)用到替換內(nèi)容中, eg.
r'\2 ...'