常用正則表達(dá)式最強(qiáng)匯總(含Python代碼舉例講解+爬蟲(chóng)實(shí)戰(zhàn))

大家好,我是辰哥~

本文帶大家學(xué)習(xí)正則表達(dá)式,并通過(guò)python代碼舉例講解常用的正則表達(dá)式

最后實(shí)戰(zhàn)爬取小說(shuō)網(wǎng)頁(yè):重點(diǎn)在于爬取的網(wǎng)頁(yè)通過(guò)正則表達(dá)式進(jìn)行解析。

正則表達(dá)式語(yǔ)法

Python的re模塊(正則表達(dá)式)提供各種正則表達(dá)式的匹配操作。在絕大多數(shù)情況下能夠有效地實(shí)現(xiàn)對(duì)復(fù)雜字符串的分析并取出相關(guān)信息。在講解如何實(shí)際應(yīng)用正則表達(dá)式之前,先教大家學(xué)習(xí)并掌握正則表達(dá)式的基本語(yǔ)法(匹配規(guī)則)。

正則表達(dá)式匹配過(guò)程如下:

(1)將定義好的正則表達(dá)式和字符串進(jìn)行比較。

(2)如果每一個(gè)字符串都能匹配,則成功;一旦有匹配不成功的字符則匹配失敗。

正則表達(dá)式規(guī)則

常見(jiàn)規(guī)則

image

數(shù)量詞匹配規(guī)則

image

邊界匹配規(guī)則
image

Re模塊

Python中使用Re庫(kù)去定義的正則表達(dá)式,常用的方法列舉如下:

lpattern對(duì)象

re.compile(string[,flag])

l匹配所用函數(shù)

re.match(pattern, string[, flags])

re.search(pattern, string[, flags])

re.split(pattern, string[, maxsplit])

re.findall(pattern, string[, flags])

re.finditer(pattern, string[, flags])

re.sub(pattern, repl, string[, count])

re.subn(pattern, repl, string[, count])

其中pattern對(duì)象是由我們傳入字符串對(duì)象,通過(guò)compile方法生成。利用這個(gè)對(duì)象來(lái)進(jìn)行下一步的匹配。針對(duì)上述列舉的各種正則表達(dá)式匹配規(guī)則和函數(shù),下面通過(guò)Python代碼進(jìn)行舉例講解。

(1) re.match(pattern, string[, flags])

match函數(shù)將會(huì)從String(待匹配的字符串)的開(kāi)頭開(kāi)始,嘗試匹配pattern,一直向后匹配。如果中途匹配pattern成功,則終止匹配,返回匹配結(jié)果。如果無(wú)法匹配或者到字符串末尾還未匹配到,則返回None。

舉例

#導(dǎo)入re模塊
import re
pattern = re.compile(r'python')
# 使用re.match匹配文本,獲得匹配結(jié)果,無(wú)法匹配時(shí)將返回None
result1 = re.match(pattern,'python')
result2 = re.match(pattern,'pythonn CQC!')
result3 = re.match(pattern,'pthon CQC!')
print(result1)
print(result2)
print(result3)
 
"""
結(jié)果:
<_sre.SRE_Match object; span=(0, 6), match='python'>
<_sre.SRE_Match object; span=(0, 6), match='python'>
None
""" 

(2) re.search(pattern, string[, flags])

Search函數(shù)會(huì)掃描整個(gè)string字符串查找匹配,存在的話返回匹配結(jié)果,不存在則返回None。

舉例:

import re
pattern = re.compile(r'python')
#從“hello pythonnnnn!”中匹配“python”
result1 = re.search(pattern,'hello pythonnnnn!')
#從“hello pyhon!”中匹配“python”
result2 = re.search(pattern,'hello pyhon!')
print(result1)
print(result2)
 
"""
結(jié)果:
<_sre.SRE_Match object; span=(6, 12), match='python'>
None
"""

(3) re.split(pattern, string[, maxsplit])

split函數(shù)可以按照pattern匹配模式將string字符串分割后返回列表,其中maxsplit參數(shù)可以指定最大分割次數(shù),不指定則將字符串全部分割。

  舉例:
import re
#以一位或者多位數(shù)字作為分割間隔
pattern = re.compile(r'\d+')
print(re.split(pattern,'python1java2php3js'))
#只分割兩次
print(re.split(pattern,'python1java2php3js',maxsplit=2))
 
"""
結(jié)果:
['python', 'java', 'php', 'js']
['python', 'java', 'php3js']
"""

(4) re.findall(pattern, string[, flags])

findall函數(shù)作用是搜索整個(gè)字符串,以列表形式返回全部能匹配的子串。

  舉例:
import re
pattern = re.compile(r'\d+')
print(re.findall(pattern,'python1java2php3js2245'))
 
"""
結(jié)果:
['1', '2', '3', '2245']
"""

(5) re.finditer(pattern, string[, flags])

finditer函數(shù)作用是搜索整個(gè)字符串,返回一個(gè)符合匹配結(jié)果(Match對(duì)象)的迭代器。

  舉例:

import re
#以一位或者多位數(shù)字作為搜索條件
pattern = re.compile(r'\d+')
#搜索結(jié)果得到一個(gè)集合,通過(guò)循環(huán)對(duì)集合遍歷輸出
for item in re.finditer(pattern,'python1java2php3js2245'):
  print(item.group())
 
"""
結(jié)果:
1
2
3
2245
"""

(6) re.sub(pattern, repl, string[, count])

先看兩個(gè)例子,然后再解釋這個(gè)sub函數(shù)的作用。

  舉例:

import re
pattern1 = re.compile(r'music')
#例1中“i love the music”里的music替換成python
print(re.sub(pattern1, 'python', 'i love the music'))
pattern2 = re.compile(r'(\d+)')
#例2中“數(shù)字123 和9”被python替換。
print(re.sub(pattern2, 'python', 'My number is 123 and my favorite number is 9'))
 
"""
結(jié)果:
i love the python
My number is python and my favorite number is python
"""

(7) re.subn(pattern, repl, string[, count])

subn可以指定替換次數(shù),不指定則默認(rèn)替換全部。

舉例:


import re
#以一位或者多位數(shù)字作為替換條件
pattern1 = re.compile(r'(\d+)')
#用“python”替換數(shù)字(一位或者多位),最后返回替換結(jié)果和替換次數(shù)
print(re.subn(pattern1, 'python', 'My number is 123 and my favorite number is 9'))
pattern2 = re.compile(r'(\d+)')
print(re.subn(pattern2, 'python', 'My number is 123 and my favorite number is 9',1))
 
"""
結(jié)果:
('My number is python and my favorite number is python', 2)
('My number is python and my favorite number is 9', 1)
"""

實(shí)戰(zhàn)

需求:提取小說(shuō)章節(jié)正文和標(biāo)題

本節(jié)通過(guò)實(shí)戰(zhàn)案例來(lái)講解正則表達(dá)式的應(yīng)用。案例目的是:提取小說(shuō)章節(jié)內(nèi)容。步驟是先采集到每一章小說(shuō)正文內(nèi)容網(wǎng)頁(yè)源碼,然后通過(guò)正則表達(dá)式將里面的正文提取出來(lái)。

這里爬取小說(shuō) 第一章 北靈院,用正則表達(dá)式提取小說(shuō)章節(jié)正文標(biāo)題

目標(biāo)鏈接:http://book.chenlove.cn/book/12242/39a44ff6dd27f.html

頁(yè)面如下:

image

分析網(wǎng)頁(yè)源碼:

image

可以看到章節(jié)標(biāo)題在h3標(biāo)簽中,其class為j_chapterName;正文內(nèi)容在p標(biāo)簽中,清楚這些之后,下面開(kāi)始編寫(xiě)代碼請(qǐng)求網(wǎng)頁(yè)源碼,并編寫(xiě)正則表達(dá)式去提取標(biāo)題和正文。

完整代碼如下:


import requests
import re
import json
# 設(shè)置代理服務(wù)器
headers = {
    'User_Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36'
}
#請(qǐng)求連接
url = "http://book.chenlove.cn/book/12242/39a44ff6dd27f.html"
response = requests.get(url, headers=headers)
if response.status_code == 200:
    # 轉(zhuǎn)化為utf-8格式,不加這條語(yǔ)句,輸出爬取的信息為亂碼
    response.encoding = 'utf8'
    #獲取到源碼
    html = response.text
    # 正則表達(dá)式解析小說(shuō)章節(jié)標(biāo)題
    pattern1 = re.compile('<h3>(.+)</h3>')
    title = re.findall(pattern1, html)[0]
    #正則表達(dá)式解析小說(shuō)章節(jié)正文內(nèi)容
    text = re.findall(r"<p>(.*?)</p>", html,re.S)[2:-1][0].split("</div>")[0]
    # 打印輸出
    print(title)
    print(text)
 
"""
結(jié)果:
第一章 北靈院
     烈日如炎,灼熱的陽(yáng)光從天空上傾灑下來(lái),令得整片大地都是處于一片蒸騰之中,楊柳微垂,......
"""

可以看到第一章的標(biāo)題和正文已經(jīng)成功提取出來(lái)了,因?yàn)檎膬?nèi)容很長(zhǎng),這里僅展示部分。

最后

本文匯總正則表達(dá)式常用的基本語(yǔ)法,并結(jié)合Python進(jìn)行舉例演示

最后實(shí)戰(zhàn)講解正則表達(dá)式在爬蟲(chóng)中的應(yīng)用。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容