前面已經(jīng)初步介紹了正則式的語法規(guī)則和re模塊的方法。
這次主要舉了幾個例子,看看re模塊在實際工作中的使用。
1. re.match
設定一個字符串
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())
輸出結果
> 2005-2018 douban.com, all rights reserved 北京豆網(wǎng)科技有限公司
- 泛匹配
result = re.match('^2005.*司$', content)
print(result.group())
輸出結果
> 2005-2018 douban.com, all rights reserved 北京豆網(wǎng)科技有限公司
- 目標匹配(括號及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))
輸出結果
> 2005-2018 douban.com, all rights reserved 北京豆網(wǎng)科技有限公司
> 2005
> ('2005', '2018') <class 'tuple'>
> 2018
- re.match從字符串的開頭匹配
(將常規(guī)匹配中表達式 改成005-\d{4}...都不能匹配成功) - group與groups的用法:
-
group()查看正則式所匹配內容 -
group(1)查看正則式中第一個括號里面的內容 -
groups()將正則式中所有括號里面的內容組成一個tuple,提取字符串要用切片的方法result.groups()[0] -
group()里面的參數(shù)是從1開始的,不是0。
-
-
匹配模式的參數(shù)使用 (re.S舉例)
將content內容中增加換行符‘\n'
content1 = '2005-2018 douban.com, all rights reserved \n 北京豆網(wǎng)科技有限公司'
使用匹配模式的參數(shù)re.S,忽略換行符匹配
(具體參數(shù)規(guī)則請查閱上次的內容)
result = re.match('^2005.*司$', content1, re.S)
result_error = re.match('^2005.*司$', content1)
print(result.group())
print(result_error)
原本正則式.*不會匹配換行符,但是填寫參數(shù)re.S后,
輸出結果就能匹配到字符串中的換行符了
> 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))
輸出結果
> 科技有限公司
- 非貪婪匹配
result2 = re.search('2018.*?(\w{6})', content)
print(result2.group(1))
輸出結果
> douban
區(qū)別:
匹配目標(\w{6})是想截取2018以后的連續(xù)6個字母數(shù)字及下劃線
貪婪匹配中.*,盡可能多的匹配到中間的字符,只剩下最后6個字符作為匹配目標
非貪婪匹配.*?,卻截取與匹配目標最接近的6個字符
3. re.findall
案例:正則式爬取豆瓣圖書相關信息
先獲得單個html源碼
url = 'https://book.douban.com/top250?icn=index-book250-all'
response = requests.get(url)
content = response.text
這里只截取書名和價格

網(wǎng)頁源碼
注意使用非貪婪匹配,否則不能截取所有信息
results = re.findall('title="(\w+)".*?<p class="pl">.*?(\d{2}\.\d{2}).*?</p>', content, re.S)
print(results)
輸出結果是由tuple組成的list
[('追風箏的人', '29.00'), ('小王子', '22.00'), ('圍城', '19.00'), ('解憂雜貨店', '39.50'), ('活著', '12.00'), ('白夜行', '29.80'), ('挪威的森林', '18.80'), ('嫌疑人X的獻身', '28.00'), ('三體', '23.00'), ('不能承受的生命之輕', '23.00'), ('紅樓夢', '59.70'), ('夢里花落知多少', '20.00'), ('看見', '39.80'), ('百年孤獨', '39.50'), ('何以笙簫默', '15.00'), ('可試讀', '19.50'), ('白夜行', '39.50'), ('三體Ⅱ', '32.00'), ('飄', '40.00'), ('送你一顆子彈', '25.00'), ('三體Ⅲ', '38.00')]
4. re.finditer
和 findall 類似,在字符串中找到正則表達式所匹配的所有子串,并把它們作為一個迭代器返回
results = re.finditer('title="(\w+)".*?<p class="pl">.*?(\d{2}\.\d{2}).*?</p>', content, re.S)
print(results)
返回一個迭代器的對象
<callable_iterator object at 0x000001D2FDA98EB8>
要用循環(huán)語句才能調用:
for result in results:
print(result.groups())
5. re.compile
用于編譯正則表達式,生成一個正則表達式(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
用于替換字符串中的匹配項
- 找出連續(xù)4個數(shù)字,替換為
hello welcome
content = '2005-2018 douban.com, all rights reserved 北京豆網(wǎng)科技有限公司'
result = re.sub('\d{4}', 'hello welcome', content, 1)
print(result)
輸出結果為
> hello welcome-2018 douban.com, all rights reserved 北京豆網(wǎng)科技有限公司
- 1表示匹配一次,所以只有2005替換了
- 參數(shù)默認為0,表示符合條件的,全部替換
- 替換括號內的內容
result = re.sub('(\d{4})-(\d{4})', r'\2 welcome', content)
print(result)
輸出結果為:
> 2018 welcome douban.com, all rights reserved 北京豆網(wǎng)科技有限公司
- 按照括號順序,可以將匹配內容調用到替換內容中, eg.
r'\2 ...'