Python高級-正則表達式
第三章 正則表達式
在開發中會有大量的字符串處理工作,其中經常會涉及到字符串格式的校驗。
1、正則表達式概述
正則表達式,又稱正規表示式、正規表示法、正規表達式、規則表達式、常規表示法(英語:Regular Expression,在代碼中常簡寫為regex、regexp或RE),是計算機科學的一個概念。正則表達式使用單個字符串來描述、匹配一系列匹配某個句法規則的字符串。在很多文本編輯器里,正則表達式通常被用來檢索、替換那些匹配某個模式的文本。
2、re模塊
一個正則表達式(或RE)指定了一集與之匹配的字符串;模塊內的函數可以讓你檢查某個字符串是否跟給定的正則表達式匹配模塊定義了幾個函數,常量,和一個例外。有些函數是編譯后的正則表達式方法的簡化版本(少了一些特性)。絕大部分重要的應用,總是會先將正則表達式編譯,之后在進行操作
那現在我們先熟悉re模塊的一簡單的方法
compile方法
re.compile(pattern[,flags])
# 作用:把正則表達式語法轉化成正則表達式對象
pattern:正則表達式語法
flags定義匹配模式包括:{
re.I:忽略大小寫
re.L:表示特殊字符集 \w,\W,\b,\B,\s,\S 依賴于當前環境
re.M:多行模式
re.S:' . '并且包括換行符在內的任意字符(注意:' . '匹配任意字符但不包 括換行符)
re.U:表示特殊字符集 \w,\d,\D,\S 依賴于 Unicode 字符屬性數據庫
}
search方法
re.search(pattern, string[, flags=0])
# 作用:掃描整個字符串,并返回第一個成功的匹配。如果匹配失敗,則返回None。
pattern : 正則表達式對象
string : 要被查找替換的原始字符串。
flags定義匹配模式包括:{
re.I:忽略大小寫
re.L:表示特殊字符集 \w,\W,\b,\B,\s,\S 依賴于當前環境
re.M:多行模式
re.S:' . '并且包括換行符在內的任意字符(注意:' . '匹配任意字符但不包括換行符)
re.U:表示特殊字符集 \w,\d,\D,\S 依賴于 Unicode 字符屬性數據庫
}
match方法
re.match(pattern, string[, flags=0])
# 作用:從起始位置開始匹配,匹配成功返回一個對象,未匹配成功返回None
pattern : 正則表達式對象
string : 需要匹配的字符串
flags定義匹配模式包括:{
re.I:忽略大小寫
re.L:表示特殊字符集 \w,\W,\b,\B,\s,\S 依賴于當前環境
re.M:多行模式
re.S:' . '并且包括換行符在內的任意字符(注意:' . '匹配任意字符但不包括換行符)
re.U:表示特殊字符集 \w,\d,\D,\S 依賴于 Unicode 字符屬性數據庫
}
這里我們分別簡單了解一下這些模塊,
1、compile方法是將正則表達式轉換成對象,
2、search和match方法是根據compile對象轉換生成好的規則,進行匹配。
那我們將上方的思考題拿下來,先看思考一下
# 導入模塊
>>> import re
# 如何判斷一個字符串是手機號呢
tel_1 = '''aesdf13811011234aa1a3hi233rhi387156340affa124564531346546afa19454132135'''
# 這里我們不說的過于復雜了,也不說特殊號碼了,簡單了解一下規則
# 1、由11位正整數字組成
# 2、第一位數字必須由1開頭,第二位數字由3-9組成
# 根據這些條件這里即可以生成一個匹配式 1[3,9]\d{9},下面我們會講解上匹配語法與規則
pattern = re.compile(r'1[3,9]\d{9}')
# 使用search方法,匹配到一個電話號碼
print(re.search(pattern, tel_1))#<re.Match object; span=(7, 18), match='13811011234'>
# 再使用match方法,輸出了None
print(re.match(pattern, tel_1))
None# -----------------------------------------------# 那我們換一個例子再看,
tel_2 = '''19454132135abuw'''
# 再將匹配表達式轉換成匹配對象
pattern = re.compile(r'1[3,9]\d{9}')
# 先使用search方法
print(re.search(pattern, tel_2))
#<re.Match object; span=(0, 11), match='19454132135'>
# 再使用match方法,看到對象響應的結果,出現了需要匹配的號碼
print(re.match(pattern, tel_2))
#<re.Match object; span=(0, 11), match='19454132135'>
我們可以發現,更多的時候,我們在字符串或者是一堆單詞內容里面不確定范圍搜索,可以使用search來進行匹配第一個最先匹配到的正常的電話號碼,而match用來匹配第一個注意是第一個字符的,這里的第一個是在被搜索的這串字符的第一位索引上的
這里面我們根據返回回來的內容,看到有三部分
1、re.Match object 對象
2、span=()搜索結果在文本索引位置
3、match匹配結果
這里我們現在就需要急切了解到兩個問題
第一、得到的匹配對象re.Match object該如何處理,以及re模塊是否存在一些其他的方法
第二、正則表達式的寫法
3、Match對象
我們來看一下,Match對象,Match對象是一次匹配的結果,包含匹配的很多信息
Match匹配對象的屬性
>>> import re
>>> tel_1 = '''aesdf13811011234aa1a3hi233rhi387156340affa124564531346546afa19454132135'''
>>> pattern = re.compile(r'1[3,9]\d{9}')
>>> results = re.search(pattern, tel_1)
# pos表示搜索的開始的位置,endpos搜索結束的位置
>>> print(results.pos, results.endpos)
0 83
# group表示匹配的結果
>>> print(results.group())
13811011234
>>> tel_2 = '''19454132135abuw'''
>>> results = re.search(pattern, tel_2)
# pos表示搜索的開始的位置,endpos搜索結束的位置
>>> print(results.pos, results.endpos)
0 15
# group表示匹配的結果
>>> print(results.group())
19454132135>>> results = re.search(pattern, tel_2)
# pos表示搜索的開始的位置,endpos搜索結束的位置
>>> print(results.pos, results.endpos)
0 15
# group表示匹配的結果
>>> print(results.group())
19454132135
4、正則表達式
構造正則表達式的方法和創建數學表達式的方法一樣。也就是用多種元字符與運算符可以將小的表達式結合在一起來創建更大的表達式。正則表達式的組件可以是單個的字符、字符集合、字符范圍、字符間的選擇或者所有這些組件的任意組合。
正則表達式是由普通字符(例如字符 a 到 z)以及特殊字符(稱為"元字符")組成的文字模式。模式描述在搜索文本時要匹配的一個或多個字符串。正則表達式作為一個模板,將某個字符模式與所搜索的字符串進行匹配元字符 (參見 python 模塊 [re 文檔](re — 正則表達式操作 — Python 3.12.4 文檔))
字符 | 功能 |
---|---|
. | 匹配任意字符(不包括換行符) |
A | 匹配開始位置,多行模式下匹配每一行的開始,(也有取反的意思,區分應用場景) |
$ | 匹配結束位置,多行模式下匹配每一行的結束 |
* | 匹配前一個元字符0到多次 |
十 | 匹配前一個元字符1到多次 |
? | 匹配前一個元字符0到1次 |
{m,n} | 匹配前一個元字符m到n |
\ | 轉義字符,跟在其后的字符將失去作為特殊元字符的含義, 例如.只能匹配.,不能再匹配任意字符 |
[] | 字符集, 一個字符的集合,可匹配其中任意一個字符 |
| | 邏輯表達式或,比如a |
(…) | 分組,默認為捕獲,即被分組的內容可以被單獨取出, 默認每個分組有個索引,從1開始,按照"("的順序決定索引值 |
(?iLmsux) | 分組中可以設置模式,iLmsux之中的每個字符代表一個模式 |
(?:…) | 分組的不捕獲模式,計算索引時會跳過這個分組 |
(?P…) | 分組的命名模式,取此分組中的內容時可以使用索引也可以使用name |
(?P=name) | 分組的引用模式,可在同一個正則表達式用引用前面命名過的正則 |
(?#…) | 注釋,不影響正則表達式其它部分 |
(?=…) | 順序肯定環視,表示所在位置右側能夠匹配括號內正則 |
(?!..) | 順序否定環視,表示所在位置右側不能匹配括號內正則 |
(?<=…) | 逆序肯定環視,表示所在位置左側能夠匹配括號內正則 |
(?<!..) | 逆序否定環視,表示所在位置左側不能匹配括號內正則 |
(?(id/name)yes|no) | 若前面指定id或name的分區匹配成功則執行yes處的正則,否則執行no處的正則 |
\number | 匹配和前面索引為number的分組捕獲到的內容一樣的字符串 |
VA | 匹配字符串開始位置,忽略多行模式 |
\Z | 匹配字符串結束位置,忽略多行模式 |
\b | 匹配位于單詞開始或結束位置的空字符串 |
\B | 匹配不位于單詞開始或結束位置的空字符串 |
\d | 匹配一個數字,相當于[0-9] |
\D | 匹配非數字,相當于[^0-9] |
\s | 匹配任意空白字符,相當于[\t\n\r\fv] |
\S | 匹配非空白字符,相當于[^\t\n\r\flv] |
\w | 匹配數字、字母、下劃線中任意一個字符,相當于[a-zA-Z0-9] |
\W | 匹配非數字、字母、下劃線中的任意字符,相當于-[^\w] |
5、表示字符
’ . ’ 用法
# 導入模塊
>>> import re
# 測試匹配任意字符(不包括換行符)使用的re中的match方法
>>> print(re.match(".","a").group())
'a'
>>> print(re.match(".","1").group())
'1'
>>> print(re.match(".","_").group())
'_'
>>> print(re.match(".","0").group())
'0'
# 只有匹配到'\n'時候提示None,說明,匹配任意字符(不包括換行符)
>>> print(re.match(".","\n"))
None
’ [ ] ’ 用法
# 導入模塊
>>> import re
# 匹配字符集,區間中的集合,可匹配其中任意一個字符,使用的re中的match方法
# 如果hello的首字符小寫,那么正則表達式需要小寫的h
>>> print(re.match("h","hello Python").group())
'h'
# 如果hello的首字符大寫,那么正則表達式需要大寫的H
>>> print(re.match("H","Hello Python").group())
'H'
# 大小寫h都可以的情況
>>> print(re.match("[hH]","hello Python").group())
'h'
>>> print(re.match("[hH]","Hello Python"