目錄
?正則表達式:
match()函數:
search()函數:
findall()函數:
正則表達式的參數:
表示字符范圍的參數:
表示字符出現的次數的參數:
表示同一類字符的參數:
貪婪和非貪婪模式:
或和組:
sub()和complie()方法:
?正則表達式
正則表達式(Regular Expression,re)是一種用于對字符串類型數據 進行高效的搜索、替換的操作。
其主要的匹配字符串的函數有三種:match(), search(),findall()
函數 | 匹配范圍 | 返回結果 | 常見用途 |
---|---|---|---|
match() | 字符串起始位置 | 匹配的對象 或?None | 驗證字符串是否以特定字符開頭 |
search() | 整個字符串 | 第一個匹配的對象 或?None | 查找字符串中是否存在某個字符 |
findall() | 整個字符串 | 所有匹配的字符串 或 元組列表 | 提取文本中所有符合條件的內容 |
match()函數:
1.
import re
message = '張三、李四、王五、趙六'
result = re.match('張三',message) #從參數2中查找滿足參數1的內容
print(result)
運行結果:
<re.Match object; span=(0, 2), match='張三'>
解析:re.match()
從字符串起始位置匹配正則表達式。此處 “張三” 位于message
開頭,匹配成功,返回包含匹配位置(span=(0,2)
)和匹配內容的Match
對象。
2.
import re
message = '張三、李四、王五、趙六'
result = re.match('三',message) #起始位置匹配不成功的話,就返回none
print(result)
運行結果:
None
解析:re.match()
僅從字符串開頭匹配。message
開頭是 “張”,而非 “三”,匹配失敗,返回None
。
search()函數:
import re
message = '張三、李四、王五、趙六、王五'
result = re.search('王五',message)
print(result)
運行結果:
<re.Match object; span=(6, 8), match='王五'>
解析:re.search()
在字符串任意位置查找第一個匹配的項。第一個 “王五” 位于索引 6-8 的位置,因此返回該位置的匹配對象。
findall()函數:
import re
message = '張三、李四、王五、趙六、王五'
result = re.findall('王五',message)#從參數2中查找滿足參數1的所有內容
print(result)
運行結果:
['王五', '王五']
解析:re.findall()
返回所有匹配的內容,以列表形式呈現。message
中出現兩次 “王五”,因此列表包含兩個元素。
正則表達式的參數:
表示字符范圍的參數:
[abc]:字符集合匹配,即匹配 abc 中的 任意一個字符。
[a-z]:范圍匹配,即匹配指定范圍內的 任意一個字符。
import re
message = 'Python93,C87,Java63,C++88'
result_1 = re.search('[cn]',message)
result_2 = re.findall('[0-9]',message)
result_3 = re.findall('[cn][0-9]',message) # 匹配字母c或n后接數字的組合
print(result_1,result_2,result_3)
運行結果:
<re.Match object; span=(5, 6), match='n'>
['9', '3', '8', '7', '6', '3', '8', '8'] ['n9']
解析:
[cn]
匹配字母c
或n
,message
中第一個符合的是Python
中的n
(索引 6)。[0-9]
匹配所有數字,提取出字符串中所有單個數字。[cn][0-9]
匹配c
或n
后接數字的組合,僅Python93
中的n9
符合。
表示字符出現的次數的參數:
符號 | 含義 | 示例與等價形式 |
---|---|---|
* | 匹配前面的子表達式任意次(≥0 次)。 | ab* ?可匹配 "a", "ab", "abb" 等。 |
+ | 匹配前面的子表達式至少一次(≥1 次)。 | ab+ ?可匹配 "ab", "abb",但不匹配 "a"。 |
? | 匹配前面的子表達式零次或一次(0 或 1 次)。 | ab? ?可匹配 "a" 或 "ab"。 |
^ | 匹配輸入字符串的開始位置。 | ^Hello ?僅匹配以 "Hello" 開頭的字符串。 |
$ | 匹配輸入字符串的結束位置。 | world$ ?僅匹配以 "world" 結尾的字符串。 |
{n} | 精確匹配前面的子表達式 n 次(n 為非負整數)。 | a{3} ?僅匹配 "aaa"。 |
{n,} | 至少匹配前面的子表達式 n 次(n 為非負整數)。 | a{2,} ?可匹配 "aa", "aaa" 等。 |
{n,m} | 最少匹配 n 次且最多匹配 m 次(n ≤ m,且均為非負整數)。 | a{1,3} ?可匹配 "a", "aa", "aaa"。 |
示例1:
import re
message = 'da2a7ddbre77yifed777ttt3fefd7777b'
result = re.findall('[a-z]*[0-9][a-z]',message)
print(result)
result = re.findall('[a-z]+[0-9][a-z]',message)
print(result)
result = re.findall('[a-z]?[0-9][a-z]',message)
print(result)
運行結果:
['da2a', '7d', '7y', '7t', 'tt3f', '7b']
['da2a', 'ttt3f']
['a2a', '7d', '7y', '7t', 't3f', '7b']
解析:正則表達式[a-z]*[0-9][a-z]
表示:
[a-z]*
:0 個或多個小寫字母;[0-9]
:1 個數字;[a-z]
:1 個小寫字母。
匹配結果為包含 “數字前后有字母” 的片段。
示例2:
import re
phone_num = input("請輸入您的手機號碼:")
result = re.findall('^1[0-9]{10}$',phone_num)
print(result)
運行結果(輸入13155558888
時):
['13155558888']
解析:正則^1[0-9]{10}$
驗證手機號:
^1
:以 1 開頭;[0-9]{10}
:緊跟 10 個數字;$
:結束符(確保無多余字符)。
匹配成功返回手機號列表,失敗返回空列表。
錯入輸入無法匹配:
如果去掉 "$" ,就不再有輸入位數限制:(即匹配足夠的數字后停止)
示例3:
import re
QQ_number = input("請輸入您的QQ號:")
result = re.match('[1-9][0-9]{4,10}$',QQ_number)
print(result)
運行結果(輸入123456
時):
<re.Match object; span=(0, 6), match='123456'>
解析:正則[1-9][0-9]{4,10}$
驗證 QQ 號:
[1-9]
:首位不為 0;[0-9]{4,10}
:后續 4-10 個數字(總長度 5-11 位)。
re.match()
從開頭匹配,符合則返回匹配對象,否則返回None
。
示例4:
import re
use_name = input("請輸入您的用戶名:")
result = re.findall('^[A-Za-z_][A-Za-z0-9_]{7,}$',use_name)
print(result)
運行結果(輸入User_1234
時):
['User_1234']
解析:正則驗證用戶名規則:
- 首位為字母或下劃線;
- 后續為字母、數字或下劃線,且總長度≥8 位。
匹配成功返回用戶名列表,否則返回空列表。
?錯誤輸入無法匹配:
表示同一類字符的參數:
元字符 | 描述 | 等價于 |
---|---|---|
\d | 匹配一個數字類字符 | [0-9] |
\D | 匹配一個非數字類字符(^ 在中括號中表示 “非”) | [^0-9] |
\s | 匹配任何不可見字符,包括空格、制表符、換頁符等 | [\f\n\r\t\v] |
\S | 匹配任何可見字符 | [^\f\n\r\t\v] |
\w | 匹配包括下畫線的任何單詞字符 | [A-Za-z0-9_] |
\W | 匹配任何非單詞字符 | [^A-Za-z0-9_] |
\b | 匹配一個單詞的邊界,即單詞和空格間的位置 | |
\B | 匹配非單詞邊界 | |
\f | 匹配一個分頁符 | |
\n | 匹配一個換行符 | |
\r | 匹配一個 Enter 鍵符 | |
\t | 匹配一個制表符 | |
\v | 匹配一個垂直制表符 | |
. | 匹配除 “\n” 和 “\r” 之外的任何單個字符 |
示例1:
import re
use_name = input("請輸入您的用戶名:")
result = re.findall('^[A-Za-z_]\w{7,}$',use_name)
print(result)
運行結果(輸入User_1234
時):
['User_1234']
解析:\w
任何單詞字符等價于[A-Za-z0-9_]
示例2:
import re
message = 'verb very never every aer_'
result = re.findall(r'\w+er\B',message)
print(result)
運行結果:
['ver', 'ver', 'ever', 'aer']
解析:
\w+er
:匹配以er
結尾的單詞片段;
\B
:非單詞邊界(即er
后緊跟其他字符,不是空格或結尾)。
示例3:
import re
message = 'verb very never every'
result = re.findall('.e',message)
print(result)
運行結果:
['ve', 've', 'ne', 've', ' e', 've']
解析:.
匹配任意字符(除換行、回車),'e'
匹配字母e
,因此.e
匹配 “任意字符 + e” 的組合。
貪婪和非貪婪模式:
貪婪模式:
嘗試匹配盡可能多的字符,只要滿足表達式要求都會匹配最多的字符
非貪婪模式:
一旦滿足表達式要求就不再繼續匹配。在次數限制操作符后面加上“?”可以將匹配模式轉換為非貪婪模式。
示例1:
import re
message = 'ccc739134792hdccc1'
result = re.findall('ccc\d+',message)
print(result)
運行結果:
['ccc739134792', 'ccc1']
解析:\d是數字類字符,+是>=1次。為貪婪模式,匹配盡可能多的數字。
示例2:
import re
message = 'ccc739134792hd'
result = re.findall('ccc\d+?',message)
print(result)
運行結果:
['ccc7']
解析:\d是數字類字符,+是>=1次,?是0次或1次,三者結合后意思是匹配 一個數量類字符。為非貪婪模式
如果去掉加號:
或和組:
示例1:
或:符合兩種情況的匹配
import re
message = 'verb very never every'
result = re.findall('\w+ev|\w+ry',message)
print(result)
運行結果:\w包括下畫線的任何單詞字符
['very', 'nev', 'every']
示例2:
將()中的表達式定義為組,并且將匹配這個表達式的字符保存到一個臨時區域,即捕獲匹配的內容
import re
message = 'verb very never every'
result = re.findall("e(.+)(.)r",message)
print(result)
運行結果:
[('rb very never ev', 'e')]
解析:()
表示分組,e(.+)(.)r
匹配:
- 以
e
開頭,以r
結尾; - 第一個分組
(.+)
:匹配e
和r
之間的多個字符; - 第二個分組
(.)
:匹配r
前的單個字符。
sub()和complie()方法:
示例1:
re.sub()
?用于在字符串中查找匹配正則表達式的部分,并替換為指定的內容
import re
content ='dh932hf9f934hfnf39d'
content = re.sub('\d','0',content)
print(content)
運行結果:
dh000hf0f000hfnf00d
解析:re.sub('\d','0',content)
將字符串中所有數字(\d
)替換為0
,非數字字符保持不變。
示例2:
re.compile()
?用于?預編譯正則表達式,提高多次匹配時的效率(避免重復解析正則表達式)。
import re
contentl ='2020 12 15 12:00'
pattern = re.compile('\d{2}:\d{2}')
print(pattern.findall(contentl))
運行結果:
['12:00']
解析:re.compile('\d{2}:\d{2}')
編譯正則表達式(匹配 “兩位數字:兩位數字” 的時間格式),再通過pattern.findall()
從字符串中提取所有符合格式的內容,此處僅12:00
符合。