Python入門進階教程-正則表達式

  • 2019 年 12 月 31 日
  • 筆記

作者:一葉

介紹:放不下靈魂的搬磚者

全文共3241字,閱讀全文需13分鐘

Python版本3.8.0,開發工具:Pycharm

正則表達式(英語:Regular Expression,在程式碼中常簡寫為 regex、regexp 或 RE)正則表達式通常被用來檢索、替換那些符合某個模式的文本

將Regular Expression(正則表達式)理解成規則表達式更好,一個規則表達式(Regular Expression)通常被稱為一個規則(Pattern),即我們需要找到與規則一致的文本。

開篇

正則表達式(Regular Expressions,通常縮寫為 Regex)是最強大且不可或缺的文本處理工具 —— 它的用處就是在文本中掃描/搜索與某一規則匹配的所有實例,並且還可以按照規則捕獲其中的部分或者全部,對它們進行替換。

01

正則表達式介紹

在規則表達式中,存在操作符和操作元,操作符存在優先順序,操作元被稱做原子

操作符優先順序(由高到低)

(先不用在意操作符的名稱,雖然也看不太懂)

 11. 轉義符號 (Escaping Symbol):   2       32. 分組、捕獲 (Grouping or Capturing):   4    (...) (?:...) (?=...) (?!...) (?<=...) (?<!...)   53. 數量 (Quantifiers)   6    a* a+ a? a{n, m}   74. 序列與定位(Sequence and Anchor)   8    abc ^ $ b B   95. 或(Alternation)  10    a|b|c  116. 原子 (Atoms)  12    a [^abc] t r n d D s S w W .

1. 本義字元

代表的就是它們的字面值,包括從 a 到 z,A 到 Z,0 到 9,還有 _ 註: 非本義字元: + * . ? – ^ $ | ( ) [ ] { } < >,建議都直接加上轉義符號 來表示

2. 集合原子

標示集合原子,使用方括弧 []。 即[abc] 的意思是說,「a or b or c」,即,abc 中的任意一個字元。

在方括弧中,我們可以使用兩個操作符:-(區間)和 ^(非)

1- [a-z] 表示從小寫字母 a 到小寫字母 z 中的任意一個字元。  2- [^abc] 表示 abc 以外的其它任意字元,即,非 [abc]。  3  4舉:beg[iau]n 能夠代表 begin、began,以及 begun。

註:一個集合原子中,^ 符號只能用一次,只能緊跟在 [ 之後。否則不起作用。

3. 類別原子

能夠代表 「一類字元」 的原子,它們都得使用轉義符號再加上另外一個符號表達

1d 任意數字;等價於 [0-9]  2D 任意非數字;等價於 [^0-9]  3w 任意本義字元;等價於 [a-zA-Z0-9_]  4W 任意非本義字元;等價於 [^a-zA-Z0-9_]  5s 任意空白;相當於 [ fnrtv](注意,方括弧內第一個字元是空格符號)  6S 任意非空白;相當於 [^ fnrtv](注意,緊隨 ^ 之後的是一個空格符號)  7.  除 r n 之外的任意字元;相當於 [^rn]

小技巧: d 是 digits; w 是 word characters; s 是 spaces

 1# 舉例   2import re   3   4str = '<dl>(843) 542-4256</dl> <dl>(431) 270-9664</dl>'   5# 找到字元串中所有"數字-數字"格式的字元,其中第一個數字是三位數,第二個數字是四位數   6pttn = r'ddd-dddd'   7print(re.findall(pttn, str))   8   9# 輸出  10['542-4256', '270-9664']

4. 邊界原子

用邊界原子指定邊界。也可以稱作 「定位操作符」。

1^ 匹配被搜索字元串的開始位置;  2$ 匹配被搜索字元串的結束位置;  3b 匹配單詞的邊界;erb,能匹配 coder 中的 er,卻不能匹配 error 中的 er;  4B 匹配非單詞邊界;erB,能匹配 error 中的 er,卻不能匹配 coder 中的 er。

註:^ 和 $ 在 Python 語言中被 A 和 Z 替代。

 1# 舉例   2import re   3   4str = 'never ever verb however everest'   5pttn = r'erb'   6print(re.findall(pttn, str))   7pttn = r'erB'   8print(re.findall(pttn, str))   9  10# 輸出  11['er', 'er', 'er']  12['er', 'er']

5. 組合原子

用圓括弧 () 將多個單字元原子組合成一個原子, () 內的字元串將被當作一整個原子

1注意:  2er 是兩個原子,'e' 和緊隨其後的 'r'  3[er] 是一個原子,或者 'e' 或者 'r';  4(er) 是一個原子,'er'

6. 數量操作符

數量操作符有:+ ? * {n, m}。 用來限定位於它們之前的原子允許出現的個數,不加數量限定則代表出現一次且僅出現一次

1+ 代表前面的原子必須至少出現一次,即: 出現次數 ≧ 1  2? 代表前面的原子最多只可以出現一次,即:0 ≦ 出現次數 ≦ 1  3* 代表前面的原子可以不出現,也可以出現一次或者多次,即: 出現次數 ≧ 0  4{n} 代表之前的原子出現確定的 n 次;  5{n,} 代表之前的原子出現至少 n 次;  6{n, m} 代表之前的原子出現至少 n 次,至多 m 次
 1# 匹配字元串   2str = ['google', 'gooogle', 'goooogle', 'goooooogle']   3   4# 遍歷字元串   5for str_per in str:   6    # o最少出現一次   7    pttn = r'go+gle'   8    print(re.findall(pttn, str_per))   9  10    # o最多出現一次  11    pttn = r'go?gle'  12    print(re.findall(pttn, str_per))  13  14    # o出現次數≧ 0  15    pttn = r'go?gle'  16    print(re.findall(pttn, str_per))  17  18    # o出現至少2次,至多5次  19    pttn = r'go{2,5}gle'  20    print(re.findall(pttn, str_per))  21  22    # 進階:聯立組合原子  23    # g 或者 o 最少出現一次  24    pttn = r'[go]+gle'  25  26    # go 最少出現一次  27    pttn = r'(go)+gle'  28    print(re.findall(pttn, str_per))

7. 或操作符 |

或操作符 | 是所有操作符中優先順序最低的

1import re  2  3str = 'begin began begun begins beginn'  4pttn = r'begin|began|begun'  5print(re.findall(pttn, str))  6  7# 輸出  8['begin', 'began', 'begun', 'begin', 'begin']

註: 方括弧的 | 不被當作特殊符號,而是被當作 | 這個符號本身。 在方括弧中的圓括弧,也被當作圓括弧 () 本身,而無分組含義。


02

正則表達式詳細使用

Python 語言通過導入re 模組使用正則表達式所有功能。

1. re.match函數

re.match 嘗試從字元串的起始位置匹配一個模式,如果不是起始位置匹配成功的話,match()就返回none。

1# 函數語法:  2# pattern:匹配的正則表達式  3# string:要匹配的字元串。  4# flags:標誌位,用於控制正則表達式的匹配方式,如:是否區分大小寫,多行匹配等等。  5re.match(pattern, string, flags=0)
1# 匹配字元串,re.I表示對大小寫不敏感  2print(re.match('Www', 'www.runoob.com', flags=re.I).span())  3  4# 輸出  5(0, 3)

2. re.search函數

掃描整個字元串並返回第一個成功的匹配。

1# 函數語法:  2# 參數使用同 match 函數  3re.search(pattern, string, flags=0)
1# 匹配字元串,re.I表示對大小寫不敏感  2print(re.search('Www', 'www.runoob.com', flags=re.I).span())  3  4# 輸出  5(0, 3)

註:re.match只匹配字元串的開始,而re.search匹配整個字元串,直到找到一個匹配。

3. re.findall函數

在字元串中找到正則表達式所匹配的所有子串,並返回一個列表,如果沒有找到匹配的,則返回空列表。

1# 函數語法:  2# string 待匹配的字元串。  3# pos 可選參數,指定字元串的起始位置,默認為 0。  4# endpos 可選參數,指定字元串的結束位置,默認為字元串的長度。  5re.findall(string[, pos[, endpos]])

註:match 和 search 是匹配一次結果,findall 匹配所有結果。

1import re   2# 查找數字   3pattern = re.compile(r'd+')   4# 查找字元串中所有的數字   5print(pattern.findall('zhiqiu 123 xiaomeng 456'))   6# 查找字元串中0-10位的所有數字   7print(pattern.findall('zhiqiu88zhiqiu123xiaomeng456', 0, 10))   8   9# 輸出  10['123', '456']  11['88']

4. re.split函數

split 方法按照能夠匹配的子串將字元串分割後返回列表

1# 函數語法:  2# pattern:匹配的正則表達式  3# string:要匹配的字元串。  4# maxsplit:分隔次數,maxsplit=1 分隔一次,默認為 0,不限制次數。  5# flags:標誌位,用於控制正則表達式的匹配方式,如:是否區分大小寫,多行匹配等等。  6re.split(pattern, string[, maxsplit=0, flags=0])
1# 通過數字作為分隔符對字元串進行分割  2print(re.split('d+', 'zhiqiu88zhiqiu123xiaomeng456'))  3  4# 輸出:  5['zhiqiu', 'zhiqiu', 'xiaomeng', '']

補充:正則表達式修飾符

1re.I    使匹配對大小寫不敏感  2re.L    做本地化識別(locale-aware)匹配  3re.M    多行匹配,影響 ^ 和 $  4re.S    使 . 匹配包括換行在內的所有字元  5re.U    根據Unicode字符集解析字元。  6re.X    該標誌通過給予你更靈活的格式以便你將正則表達式寫得更易於理解。

正則表達式是Python中一個超級實用的一個知識點,不論是在爬蟲的網頁解析還是在數據清洗中,都很實用,且非常高效,建議掌握!

下節將介紹Python 多執行緒VS多進程

Python系列

Python系列會持續更新,從基礎入門到進階技巧,從編程語法到項目實戰。若您在閱讀的過程中發現文章存在錯誤,煩請指正,非常感謝;若您在閱讀的過程中能有所收穫,歡迎一起分享交流。

如果你也想和我一起學習Python,關注我吧!

學習Python,我們不只是說說而已

End