一 正則表達式庫
正則表達式是文本處理中不可或缺的強大工具,Python通過re
模塊提供了完整的正則表達式支持。本文將詳細介紹re
模塊中最常用的match()
、search()
和findall()
函數,以及貪婪模式與非貪婪模式的區別,幫助讀者掌握Python中正則表達式的核心用法。
1. re.match()函數:從字符串開頭匹配
re.match()
是正則表達式最基本的函數之一,它嘗試從字符串的起始位置匹配一個模式。
基本語法與參數
re.match(pattern, string, flags=0)
- ?pattern?:要匹配的正則表達式字符串或預編譯的正則對象
- ?string?:要匹配的目標字符串
- ?flags?:可選標志,用于控制正則表達式的匹配方式
返回值特性
- 匹配成功時返回
Match
對象 - 匹配失敗時返回
None
典型使用示例
import rea='1,2,3,4,5'result1=re.match('1,',a)#必須以這個參數開頭才行
result2=re.match('2',a)print(result1) #返回match對象
print(result2) #結果為空
<re.Match object; span=(0, 2), match='1,'>
其中span參數代表匹配成功 的起始和末尾的位置。match代表匹配的值為什么
2. re.search()函數:掃描整個字符串
與match()
不同,re.search()
會掃描整個字符串查找第一個匹配項,不限于字符串開頭。
基本語法
re.search(pattern, string, flags=0)
參數與match()
相同,但行為不同。
import re
a='1,2,3,4,5,3'
result=re.search('3',a) #可以不以這個參數開頭,但只返回第一個匹配的信息
print(result)
<re.Match object; span=(4, 5), match='3'>
?根據輸出結果我們可以看出,search()只返回了第一個查到的值的信息。
與match()的關鍵區別
特性 | re.match() | re.search() |
---|---|---|
匹配位置 | 僅字符串開頭 | 字符串任意位置 |
使用頻率 | 較少 | 較多 |
性能 | 稍快 | 稍慢 |
典型用途 | 驗證開頭格式 | 查找內容 |
3. re.findall()函數:查找所有匹配項
re.findall()
返回字符串中所有與模式匹配的非重疊匹配項列表。
基本語法
re.findall(pattern, string, flags=0)
返回值特點
- 返回包含所有匹配子串的列表
- 沒有匹配時返回空列表
- 如果正則中有分組,則返回分組元組列表
import re
a='as1m,23f,asd3,23f,112'
res1=re.findall('2',a)
print(res1)
['2', '2', '2']
?可以看出,這個把匹配的所有結果都返回了,但我們也會發現,這個返回的是一個列表形式,很利于處理。
與match/search的區別
match
:只在開頭查找單個匹配search
:在整個字符串查找單個匹配findall
:查找所有非重疊匹配
前面只是開胃小菜,下面請看他們結合正則表達式所展現的絢麗操作吧
4 表示字符范圍
????????先舉例子再說概念
import re
massage='pig98dog80'
res1=re.findall('[io]',massage)
res2=re.findall('[a-z]',massage)
res3=re.findall('[0-9]',massage)
print(res1)
print(res2)
print(res3)
輸出
['i', 'o']
['p', 'i', 'g', 'd', 'o', 'g']
['9', '8', '8', '0']
?根據上面實例我們可以看出
[io]所表示的是在這個字符串中,出現i或o都會被提取出來,類比,我們也可以想到[90]表示的不是90,而是表示這個‘9’和‘0’兩個字符
[a-z]所表示的是在這個字符串中,出現在a-z范圍中的都會被提取出來
[0-9]所表示的是在這個字符串中,出現在0-9范圍中的都會被提取出來
5 表示字符出現的次數
還是先舉例子再說概念
import remassage='abcdacdabb'
res=re.findall('ab*',massage)
print('ab*型:',res)res1=re.findall('ab+',massage)
print('ab+型:',res1)res2=re.findall('ab?',massage)
print('ab?型:',res2)
結果
ab*型: ['ab', 'a', 'abb']
ab+型: ['ab', 'abb']
ab?型: ['ab', 'a', 'ab']
?根據這個結果,在格式上我們可以看出區別,b后面跟的分別是*+?,然后結果也很明顯,第一種b分別出現了0,1,2次,第二種b分別出線了1,2次,第三種情況出現了1,0,1次
我們我們可以知道
ab*這種類型,可以提取*前面的數據(字母,數字,或者符號)出現任意次數的情況
ab+這種類型,可以提取*前面的數據(字母,數字,或者符號)最少出現一次的類型
ab*這種類型,可以提取*前面的數據(字母,數字,或者符號)出現0-1次的類型
import re
message='0123456'
mes=re.findall('^0',message)
mes1=re.findall('^6',message)
mes2=re.findall('0$',message)
mes3=re.findall('6$',message)
print('^0型',mes)
print('^6型',mes1)
print('0$型',mes2)
print('6$型',mes3)
輸出
^0型 ['0']
^6型 []
0$型 []
6$型 ['6']
?我們可以看出在對于同一串字符串,當0在行首時^0就可以識別出來有結果,^6就返回空值,同理$也是
所以
^所選這的是這個字符后面在行首的情況
$所選這的是這個字符前面在行尾的情況
res=re.findall('f[o]{3}',a)
res1=re.findall('f[o]{3,}',a)
res2=re.findall('f[o]{3,6}',a)
print(res)
print(res1)
print(res2)
?結果
['fooo']
['foooooooooooo']
['foooooo']
?這個我們可以看出[o]{3}就對于ooo,[o]{3,}結果就是取了全部的o,[o]{3,6}取了最大6個o
總結
ab*這種類型,可以提取*前面的數據(字母,數字,或者符號)出現任意次數的情況
ab+這種類型,可以提取*前面的數據(字母,數字,或者符號)最少出現一次的類型
ab*這種類型,可以提取*前面的數據(字母,數字,或者符號)出現0-1次的類型
^所選這的是這個字符后面在行首的情況
$所選這的是這個字符前面在行尾的情況
[o]{3} 表示3個
[o]{3,} 表示3個以上
{o]{3,6} 表示3-6個但一般沒有參數控制會是6個
6 表示同一類字符
正則表達式元字符詳解
以下是對常用正則表達式元字符的解釋和用法說明:
\d
匹配任意數字字符,等價于 [0-9]
。例如匹配電話號碼中的數字部分。
\D
匹配任意非數字字符,等價于 [^0-9]
。例如匹配非數字分隔符。
\s
匹配任意空白字符,包括空格、制表符、換行符等。例如匹配文本中的空格分隔符。
\S
匹配任意非空白字符。例如匹配連續的非空白文本。
\w
匹配任意單詞字符,包括字母、數字和下劃線,等價于 [A-Za-z0-9_]
。例如匹配變量名。
\W
匹配任意非單詞字符。例如匹配特殊符號。
\b
匹配單詞邊界。例如精確匹配整個單詞 "the" 可以寫作 \bthe\b
。
\B
匹配非單詞邊界。例如匹配 "the" 但排除 "there" 中的 "the"。
\f
匹配換頁符(Form feed)。
\n
匹配換行符(Line feed)。
\r
匹配回車符(Carriage return)。
\v
匹配垂直制表符(Vertical tab)。
.
匹配除換行符外的任意單個字符。例如匹配 "a.c" 可以匹配 "abc"、"aXc" 等。
使用示例
// 匹配所有數字
a = "123abc".match(/\d/g); // ["1", "2", "3"]// 匹配非數字
b = "123abc".match(/\D/g); // ["a", "b", "c"]// 匹配空白字符
c = "a b\tc".match(/\s/g); // [" ", "\t"]// 匹配單詞邊界
d = "hello world".match(/\b\w+\b/g); // ["hello", "world"]
這些元字符可以組合使用構建更復雜的正則表達式模式,滿足各種文本匹配需求。
6. 貪婪模式與非貪婪模式
正則表達式中的量詞(如*
, +
, ?
, {}
)默認采用貪婪匹配,會盡可能多地匹配字符。通過在量詞后添加?
可啟用非貪婪匹配,盡可能少地匹配字符。
貪婪匹配示例
text = "Here is <div>sometext</div> with <div>tags</div>."
pattern = r'<.*>'
match = re.search(pattern, text)
print(match.group()) # 輸出: <div>sometext</div> with <div>tags</div>
非貪婪匹配示例
pattern = r'<.*?>'
matches = re.findall(pattern, text)
print(matches) # 輸出: ['<div>', '</div>', '<div>', '</div>']
關鍵區別總結
模式 | 表示方法 | 匹配行為 | 適用場景 |
---|---|---|---|
貪婪 | * , + , ? , {} | 盡可能多匹配 | 提取最大可能內容 |
非貪婪 | *? , +? , ?? , {}? | 盡可能少匹配 | 提取最小單位內容 |
綜合應用建議
- ?性能考慮?:對于頻繁使用的正則表達式,使用
re.compile()
預編譯可提高效率 - ?錯誤處理?:總是檢查匹配結果是否為None再調用group()
- ?模式選擇?:
- 驗證字符串格式→
match
- 查找內容→
search
- 提取所有匹配→
findall
- 驗證字符串格式→
- ?貪婪控制?:處理HTML/XML等嵌套結構時,非貪婪模式通常更安全
通過掌握這些核心函數和模式,您將能夠高效處理大多數文本匹配和提取任務。正則表達式雖然復雜,但一旦掌握將成為您文本處理的強大武器。
7 或和組
或用|表示
組用(表達式)
5實戰
讀取html中的內容
import re
f1=open(r'D:\培訓\中國城市名稱大全.html','r',encoding='utf-8')
f2=open('城市大全.csv1','w')
ls=[]
for line in f1:# <div class="para" label-module="para">鄭州市 洛陽市 焦作市 商丘市 信陽市 周口市 鶴壁市 安陽市 濮陽市 駐馬店市</div>res=re.findall('<div class="para" label-module="para">(.+)</div>', line)if len(res)>0:ls = ls+res# print(re.findall("para>(.+)<", line))
for i in ls:f2.write(str(i)+',')# print(i)
f1.close()
f2.close()
二 第三方庫?
第三方庫,我們用一般用 pip在cmd終端安裝,也可以在pycharm終端安裝。
主要通過
?
?我們還可以在后面加
-i https://pypi.tuna.tsinghua.edu.cn/simple
來使用清華源的鏡像源來安裝