python爬蟲之正則表達式和re庫的使用(如果我都懂了,那你看這個也一定可以懂)

python爬蟲之正則表達式和re庫的使用

正則表達式

  • 啥是正則表達式
    • 用來簡潔表達一組字符串的表達式,簡而言之就是找字符串的規律,用簡短的表達式來替代字符串
    • 正則表達式 = 具有相應特徵的字符串

如下圖,顯而易見的開頭是P,後面有相同的若干個Y重複
在這裏插入圖片描述

  • 正則表達式一般用在哪裏?

    • 編譯程序中的語法分析器(上編譯原理的時候學過)
    • 查找或替換一組字符串(一看它的能力就知道)
    • 表達文本類型的特徵,用於查找病毒或者判斷入侵等
    • 總之作用都比較厲害,關鍵還是從字符串出發
  • 正則表達式的使用

    • 語法——這就比較枯燥,不用記住,常回來看看就行了
操作符 說明 實例
. 表示任何單個字符
[ ] 字符集,對單個字符給出取值範圍 [abc]表示a、b、c,[a‐z]表示a到z單個字符
[^ ] 非字符集,對單個字符給出排除範圍 [^abc]表示非a或b或c的單個字符
* 前一個字符0次或無限次擴展 abc* 表示 ab、abc、abcc、abccc等
+ 表示一個字符1次或者無限次擴展 abc+表示abc,abcc,abccc
表示一個字符0次或者是1次擴展 abc?表示ab,abc
| 邏輯或,左右任選一個都可以 abc|def 表示abc,def
{m} 前一個字符擴展m次 ab{2}c表示abbc
{m,n} 前一個字符擴展m至n次(左閉右閉) ab{1,2}c表示abc,abbc
^ 匹配字符串開頭 ^abc表示以abc爲開頭的字符串
$ 匹配字符串結尾 abc$表示以abc爲結尾的字符串
() 分組標記,內部只能使用|操作符 (abc)表示abc,(abc
\d 數字,等價於[0-9]
\w 單詞字符,等價於[A-Z a-z 0 - 9_]
  • 常見的經典的正則表達式

還是挺有意思的,雖然以前基本看不懂

正則表達式 實際意義
^ [A‐Za‐z]+$ 以26個字母開頭和結尾的字符串
^ [A‐Za‐z0‐9]+$ 由26個字母和數字爲開頭和結尾的字符串
^‐?\d+$ 整數形式的字符串(以負號開頭,並且以若干個數字爲結尾)
^ [0‐9] * [1‐9][0‐9] * $
[1‐9]\d{5} 中國境內郵政編碼,6位(開頭是以1到9,後接5個數字)
[\u4e00‐\u9fa5] 匹配中文字符(這個完全不知道,屬於拓展吧)
\d{3}‐\d{8}|\d{4}‐\d{7} 國內的電話號碼
(([1‐9]?\d 1\d{2}

python的re庫的使用

  • 常用的函數說明

在這裏插入圖片描述

兩種調用方式
  • re庫函數,加函數名直接調用
match = re.search(r'[1-9]\d{5}',"BIT 100081")
  • 調用compile函數,將正則表達式的文本式,編譯成對應的正則表達式
regex = re.compile(r'[1-9]\d{5}')
regex.search("BIT 1000081")
返回的match對象是啥
  • 簡單的說,Match對象是上述函數一次匹配的結果
    • 屬性
屬性 說明
match.string 待匹配的文本
match.re 匹配使用的正則表達式
match.pos 搜索文本的開始位置
match.endpos 搜索文本的結束位置
  • 方法
方法 說明
match.group(0) 獲取匹配後的字符串
match.start() 匹配字符串在原始字符串的開始位置
match.end() 匹配字符串在原始字符串中的結束位置
match.span() 返回(開始的位置,結束的位置)

注意:使用match一定判定一下是否匹配到

然後再逐個對re方法進行講解和示例
  • re.search(pattern,string,flags)
    • 作用:從頭到尾匹配一個正則表達式,返回第一個匹配到的位置
    • pattern:用於匹配的正則表達式,注意一定加上“r”區分常規的字符串.。如:r’[1-9]\d{5}’
    • string:待匹配的字符串
    • flags:正則表達式使用時的控制標記

在這裏插入圖片描述

代碼:
方式一:

import re
match = re.search(r'[1-9]\d{5}',"BIT 100081")
# 注意:正則表達式之前一定要加上r,以示區分
print(type(match))
print("待匹配的字符串",match.string)
print("正則表達式",match.re)
print("匹配字符串的區間:",match.span())
if match:
    print("match匹配的group對象:",match.group(0))

在這裏插入圖片描述
方式二

regex = re.compile(r'[1-9]\d{5}')
match1 = regex.search("BIT 1000081")
if match1:
    print(match1.group(0))

在這裏插入圖片描述

  • re.match(pattern,string,flags)
    • 作用:匹配字符串的開頭,看看是不是符合正則表達式
    • 返回match對象
參數 作用
pattern 用於匹配的正則表達式,注意一定加上“r”區分常規的字符串.。如:r’[1-9]\d{5}’
string 待匹配的字符串
flags 正則表達式使用時的控制標記(跟上面一樣,不講了)

代碼:

import re
# 方式一
match = re.match(r'[1-9]\d{5}',"BIT 100081")
# 注意:正則表達式之前一定要加上r,以示區分
if match:
    print("方式1.match匹配的group對象:",match.group(0))
# 方式二
regex = re.compile(r'[1-9]\d{5}')
match1 = regex.match("BIT 1000081")
if match1:
    print("方式2.match匹配的group對象:",match1.group(0))

沒有匹配到,因爲開頭都不是符合正則表達式的字符串
在這裏插入圖片描述

  • re.findall(pattern,string,flags)
    • 作用:匹配完整字符串,將符合正則表達式的結果保存在列表中,並返回
    • 包含所有匹配對象的列表
參數 作用
pattern 用於匹配的正則表達式,注意一定加上“r”區分常規的字符串.。如:r’[1-9]\d{5}’
string 待匹配的字符串
flags 正則表達式使用時的控制標記(跟上面一樣,不講了)

代碼:

import re
# 方式一
resList = re.findall(r'[1-9]\d{5}',"BIT 100081,shanghai 200237")
# 注意:正則表達式之前一定要加上r,以示區分
print("方式1.findall匹配的group對象:",resList)
# 方式二
regex = re.compile(r'[1-9]\d{5}')
resList2 = regex.findall("BIT 100081,shanghai 200237")
print("方式1.findall匹配的group對象:",resList2)

在這裏插入圖片描述

  • re.split(pattern,string,flags)
    • 作用:將字符串按照正則表達式匹配結果進行分割,返回列表
參數 作用
pattern 用於匹配的正則表達式,注意一定加上“r”區分常規的字符串.。如:r’[1-9]\d{5}’
string 待匹配的字符串
maxsplit = 0 最大分割數,剩餘部分作爲最後一個元素輸出
flags 正則表達式使用時的控制標記(跟上面一樣,不講了)

代碼

import re
# 方法一
resList = re.split(r'[1-9]\d{5}','BIT 100081 Shanghai 200237 Jiangsu 221100',maxsplit=1)
print(resList)
# 方法二
regex = re.compile(r'[1-9]\d{5}')
resList1 = regex.split('BIT 100081 Shanghai 200237 Jiangsu 221100')
# 沒有對maxsplit進行說明,那就是指所有匹配的都進行分配
print(resList1)

結果:
在這裏插入圖片描述

  • re.finditer(pattern,string,flags)
    • 作用:搜索字符串,返回一個匹配結果的迭代類型,每個迭代元素是match對象
參數 作用
pattern 用於匹配的正則表達式,注意一定加上“r”區分常規的字符串.。如:r’[1-9]\d{5}’
string 待匹配的字符串
flags 正則表達式使用時的控制標記(跟上面一樣,不講了)
import re
# 方法一
for m in re.finditer(r'[1-9]\d{5}','BIT 100081 Shanghai 200237 Jiangsu 221100'):
    if m:
        print(m.group(0))
print()
# 方法二
regex = re.compile(r'[1-9]\d{5}')
for m in regex.finditer('BIT 100081 Shanghai 200237 Jiangsu 221100'):
    if m:
        print(m.group(0))

結果
在這裏插入圖片描述

  • re.sub(pattern,string,flags)
    • 作用:在一個字符串中所有符合正則表達式的字符串替換成別的字符串
    • 返回:替換之後的字符串
參數 作用
pattern 用於匹配的正則表達式,注意一定加上“r”區分常規的字符串.。如:r’[1-9]\d{5}’
repl 替換匹配的字符串的字符串
string 待匹配的字符串
count 匹配的最大的替換次數
flags 正則表達式使用時的控制標記(跟上面一樣,不講了)

代碼:

import re
# 方法一
resString = re.sub(r'[1-9]\d{5}',"郵編","BIT 100081  Shanghai200237  Jiangsu 221100")
print(resString)
# 方法二
regex = re.compile(r'[1-9]\d{5}')
resString1 = regex.sub("郵編","BIT 100081  Shanghai200237  Jiangsu 221100")
print(resString1)

結果:
在這裏插入圖片描述

基本上都講完了,但是還有一個注意點
  • 當匹配帶長度的字符串時,默認匹配最長的字符串,俗稱貪婪匹配,啥意思?看下圖
>>> import re
>>> match = re.search(r'PY.*N','PYANBNCNDN')
>>> match.group(0)

在這裏插入圖片描述
對於待匹配的字符而言,PYANBNCNDN,其中分別有PTAN,PYANBN,PYANBNCN,PYANBNCNDN字符串都是符合匹配的結果的,python默認是返回最長的

  • 但是有的時候,我們想用到最短的匹配字符串怎麼辦?
    • 加上“?”,正則表達式中表示對應的字符串出現0次或者是1次擴展
match = re.search(r'PY.*?',"PYANBNCNDN")
print(match.group(0))

結果
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章