大家好,我是辰哥~

本文帶大家學習正則表示式,並通過python程式碼舉例講解常用的正則表示式

最後實戰爬取小說網頁:重點在於爬取的網頁通過正則表示式進行解析。

正則表示式語法

Python的re模組(正則表示式)提供各種正則表示式的匹配操作。在絕大多數情況下能夠有效地實現對複雜字串的分析並取出相關資訊。在講解如何實際應用正則表示式之前,先教大家學習並掌握正則表示式的基本語法(匹配規則)。

正則表示式匹配過程如下:

(1)將定義好的正則表示式和字串進行比較。

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

正則表示式規則

常見規則

數量詞匹配規則



邊界匹配規則

Re模組

Python中使用Re庫去定義的正則表示式,常用的方法列舉如下:

lpattern物件

re.compile(string[,flag])

l匹配所用函式

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物件是由我們傳入字串物件,通過compile方法生成。利用這個物件來進行下一步的匹配。針對上述列舉的各種正則表示式匹配規則和函式,下面通過Python程式碼進行舉例講解。

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

match函式將會從String(待匹配的字串)的開頭開始,嘗試匹配pattern,一直向後匹配。如果中途匹配pattern成功,則終止匹配,返回匹配結果。如果無法匹配或者到字串末尾還未匹配到,則返回None。

舉例

#匯入re模組
import re
pattern = re.compile(r'python')
# 使用re.match匹配文字,獲得匹配結果,無法匹配時將返回None
result1 = re.match(pattern,'python')
result2 = re.match(pattern,'pythonn CQC!')
result3 = re.match(pattern,'pthon CQC!')
print(result1)
print(result2)
print(result3) """
結果:
<_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函式會掃描整個string字串查詢匹配,存在的話返回匹配結果,不存在則返回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) """
結果:
<_sre.SRE_Match object; span=(6, 12), match='python'>
None
"""

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

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

舉例:

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

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

findall函式作用是搜尋整個字串,以列表形式返回全部能匹配的子串。

舉例:

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

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

finditer函式作用是搜尋整個字串,返回一個符合匹配結果(Match物件)的迭代器。

舉例:


import re
#以一位或者多位數字作為搜尋條件
pattern = re.compile(r'\d+')
#搜尋結果得到一個集合,通過迴圈對集合遍歷輸出
for item in re.finditer(pattern,'python1java2php3js2245'):
print(item.group()) """
結果:
1
2
3
2245
"""

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

先看兩個例子,然後再解釋這個sub函式的作用。

舉例:


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中“數字123 和9”被python替換。
print(re.sub(pattern2, 'python', 'My number is 123 and my favorite number is 9')) """
結果:
i love the python
My number is python and my favorite number is python
"""

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

subn可以指定替換次數,不指定則預設替換全部。

舉例:


import re
#以一位或者多位數字作為替換條件
pattern1 = re.compile(r'(\d+)')
#用“python”替換數字(一位或者多位),最後返回替換結果和替換次數
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)) """
結果:
('My number is python and my favorite number is python', 2)
('My number is python and my favorite number is 9', 1)
"""

實戰

需求:提取小說章節正文和標題

本節通過實戰案例來講解正則表示式的應用。案例目的是:提取小說章節內容。步驟是先採集到每一章小說正文內容網頁原始碼,然後通過正則表示式將裡面的正文提取出來。

這裡爬取小說  第一章 北靈院,用正則表示式提取小說章節正文標題

目標連結:http://book.chenlove.cn/book/12242/39a44ff6dd27f.html

頁面如下:

分析網頁原始碼:

可以看到章節標題在h3標籤中,其class為j_chapterName;正文內容在p標籤中,清楚這些之後,下面開始編寫程式碼請求網頁原始碼,並編寫正則表示式去提取標題和正文。

完整程式碼如下:


import requests
import re
import json
# 設定代理伺服器
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'
}
#請求連線
url = "http://book.chenlove.cn/book/12242/39a44ff6dd27f.html"
response = requests.get(url, headers=headers)
if response.status_code == 200:
# 轉化為utf-8格式,不加這條語句,輸出爬取的資訊為亂碼
response.encoding = 'utf8'
#獲取到原始碼
html = response.text
# 正則表示式解析小說章節標題
pattern1 = re.compile('<h3>(.+)</h3>')
title = re.findall(pattern1, html)[0]
#正則表示式解析小說章節正文內容
text = re.findall(r"<p>(.*?)</p>", html,re.S)[2:-1][0].split("</div>")[0]
# 列印輸出
print(title)
print(text) """
結果:
第一章 北靈院
烈日如炎,灼熱的陽光從天空上傾灑下來,令得整片大地都是處於一片蒸騰之中,楊柳微垂,......
"""

可以看到第一章的標題和正文已經成功提取出來了,因為正文內容很長,這裡僅展示部分。

最後

本文彙總正則表示式常用的基本語法,並結合Python進行舉例演示

最後實戰講解正則表示式在爬蟲中的應用。