Python正則表達式,這一篇就夠了!

2021-02-18 裸睡的豬
之前我們講解了 正則表達式 的起源、發展、流派、語法、引擎、優化等相關知識,今天我們主要來學習一下 正則表達式在 Python語言 中的應用!大多數程式語言的正則表達式設計都師從Perl,所以語法基本相似,不同的是每種語言都有自己的函數去支持正則,今天我們就來學習 Python中關於 正則表達式的函數。re模塊主要定義了9個常量、12個函數、1個異常,每個常量和函數豬哥都會通過實際代碼案例講解,讓大家能更直觀的了解其作用!註:為避免出現代碼格式錯亂,豬哥儘量使用代碼截圖演示哦。一、re模塊簡介聊到Python正則表達式的支持,首先肯定會想到re庫,這是一個Python處理文本的標準庫標準庫的意思表示這是一個Python內置模塊,不需要額外下載,目前Python內置模塊大概有300個。可以在這裡查看Python所有的內置模塊:https://docs.python.org/3/py-modindex.html#cap-r因為re是內置模塊,所以不需要再下載,使用時直接引入即可:re模塊官方文檔:https://docs.python.org/zh-cn/3.8/library/re.htmlre模塊庫源碼:https://github.com/python/cpython/blob/3.8/Lib/re.py二、re模塊常量上圖我們可以看到,所有的常量都是在RegexFlag枚舉類來實現,這是在Python 3.6做的改版。在Python 3.6以前版本是直接將常量寫在re.py中,使用枚舉的好處就是方便管理和使用!下面我們來快速學習這些常量的作用及如何使用他們,按常用度排序!1. IGNORECASE語法: re.IGNORECASE 或簡寫為 re.I在默認匹配模式下大寫字母B無法匹配小寫字母b,而在 忽略大小寫 模式下是可以的。2. ASCII作用: 顧名思義,ASCII表示ASCII碼的意思,讓 \w, \W, \b, \B, \d, \D, \s 和 \S 只匹配ASCII,而不是Unicode。
在默認匹配模式下\w+匹配到了所有字符串,而在ASCII模式下,只匹配到了a、b、c(ASCII編碼支持的字符)。注意:這隻對字符串匹配模式有效,對字節匹配模式無效。3. DOTALL作用: DOT表示.,ALL表示所有,連起來就是.匹配所有,包括換行符\n。默認模式下.是不能匹配行符\n的在默認匹配模式下.並沒有匹配換行符\n,而是將字符串分開匹配;而在re.DOTALL模式下,換行符\n與字符串一起被匹配到。4. MULTILINE語法: re.MULTILINE 或簡寫為 re.M作用:多行模式,當某字符串中有換行符\n,默認模式下是不支持換行符特性的,比如:行開頭 和 行結尾,而多行模式下是支持匹配行開頭的。正則表達式中^表示匹配行的開頭,默認模式下它只能匹配字符串的開頭;而在多行模式下,它還可以匹配 換行符\n後面的字符。注意:正則語法中^匹配行開頭、\A匹配字符串開頭,單行模式下它兩效果一致,多行模式下\A不能識別\n。5. VERBOSE
默認模式下並不能識別正則表達式中的注釋,而詳細模式是可以識別的。當一個正則表達式十分複雜的時候,詳細模式或許能為你提供另一種注釋方式,但它不應該成為炫技的手段,建議謹慎考慮後使用!6.LOCALE作用: 由當前語言區域決定 \w, \W, \b, \B 和大小寫敏感匹配,這個標記只能對byte樣式有效。這個標記官方已經不推薦使用,因為語言區域機制很不可靠,它一次只能處理一個 「習慣」,而且只對8位字節有效。注意: 由於這個標記官方已經不推薦使用,而且豬哥也沒使用過,所以就不給出實際的案例!7.UNICODE作用: 與 ASCII 模式類似,匹配unicode編碼支持的字符,但是 Python 3 默認字符串已經是Unicode,所以有點冗餘。8. DEBUG雖然debug模式下確實會列印編譯信息,但豬哥並不理解這是什麼語言 以及表達的含義,希望了解的朋友能不吝賜教。9.TEMPLATE語法: re.TEMPLATE  或簡寫為 re.T作用: 豬哥也沒搞懂TEMPLATE的具體用處,源碼注釋中寫著:disable backtracking(禁用回溯),有了解的同學可以留言告知!10. 常量總結9個常量中,前5個(IGNORECASE、ASCII、DOTALL、MULTILINE、VERBOSE)有用處,兩個(LOCALE、UNICODE)官方不建議使用、兩個(TEMPLATE、DEBUG)試驗性功能,不能依賴。常量可疊加使用,因為常量值都是2的冪次方值,所以是可以疊加使用的,疊加時請使用 | 符號,請勿使用+ 符號!最後來一張思維導圖總結一下re模塊中的常量吧,需要高清圖或者xmind文件的同學可在文章末尾獲取。
三、re模塊函數re模塊有12個函數,豬哥將以功能分類來講解;這樣更具有比較性,同時也方便記憶。1.查找一個匹配項查找並返回一個匹配項的函數有3個:search、match、fullmatch,他們的區別分別是:

search 查找任意位置的匹配項

match 必須從字符串開頭匹配

fullmatch 整個字符串與正則完全匹配

案例1中search函數是在字符串中任意位置匹配,只要有符合正則表達式的字符串就匹配成功,其實有兩個匹配項,但search函數值返回一個。而match函數是要從頭開始匹配,而字符串開頭多了個字母a,所以無法匹配,fullmatch函數需要完全相同,故也不匹配!案例2刪除了text最開頭的字母a,這樣match函數就可以匹配啦,而fullmatch函數依然不能完全匹配!案例3:

案例3中,我們只留下一段文字,並且與正則表達式一致;這時fullmatch函數終於可以匹配了。完整案例:

注意:查找 一個匹配項 返回的都是一個匹配對象(Match)。2.查找多個匹配項講完查找一項,現在來看看查找多項吧,查找多項函數主要有:findall函數finditer函數

findall 從字符串任意位置查找,返回一個列表

finditer:從字符串任意位置查找,返回一個迭代器

兩個方法基本類似,只不過一個是返回列表,一個是返回迭代器。我們知道列表是一次性生成在內存中,而迭代器是需要使用時一點一點生成出來的,內存使用更優。
如果可能存在大量的匹配項的話,建議使用finditer函數,一般情況使用findall函數基本沒啥影響。3.分割re.split(pattern, string, maxsplit=0, flags=0) 函數:用 pattern 分開 string , maxsplit表示最多進行分割次數, flags表示模式,就是上面我們講解的常量!注意:str模塊也有一個 split函數 ,那這兩個函數該怎麼選呢?
str.split函數功能簡單,不支持正則分割,而re.split支持正則。關於二者的速度如何? 豬哥實際測試了一下,在相同數據量的情況下使用re.split函數與str.split函數執行次數  與 執行時間 對比圖:

通過上圖對比發現,1000次循環以內str.split函數更快,而循環次數1000次以上後re.split函數明顯更快,而且次數越多差距越大!所以結論是:在 不需要正則支持 且 數據量和數次不多 的情況下使用str.split函數更合適,反之則使用re.split函數4.替換替換主要有sub函數subn函數,他們功能類似!re.sub(pattern, repl, string, count=0, flags=0) 函數參數講解:repl替換掉string中被pattern匹配的字符, count表示最大替換次數,flags表示正則表達式的常量。值得注意的是:sub函數中的入參:repl替換內容既可以是字符串,也可以是一個函數哦! 如果repl為函數時,只能有一個入參:Match匹配對象。re.subn(pattern, repl, string, count=0, flags=0) 函數與 re.sub函數 功能一致,只不過返回一個元組 (字符串, 替換次數)。
5.編譯正則對象compile函數template函數 將正則表達式的樣式編譯為一個 正則表達式對象 (正則對象Pattern),這個對象與re模塊有同樣的正則函數(後面我們會講解Pattern正則對象)。

template函數compile函數 類似,只不過是增加了我們之前說的re.TEMPLATE 模式,我們可以看看源碼。
6.其他re.escape(pattern) 可以轉義正則表達式中具有特殊含義的字符,比如:. 或者 * ,舉個實際的案例:

re.escape(pattern) 看似非常好用省去了我們自己加轉義,但是使用它很容易出現轉義錯誤的問題,所以並不建議使用它轉義,而建議大家自己手動轉義re.purge() 函數作用就是清除 正則表達式緩存,具體有什麼緩存呢?我們來看看源碼就知道它背地裡幹了 什麼:

看方法大概是清除緩存吧,我們再來看看具體的案例:

豬哥在兩個案例之間使用了re.purge() 函數清除緩存,然後分別比較前後案例源碼裡面的緩存,看看是否有變化!
7.總結同樣,最後來一張思維導圖總結一下re模塊中的函數吧,需要高清圖或者xmind文件的同學可在末尾獲取。
四、re模塊異常re模塊還包含了一個正則表達式的編譯錯誤,當我們給出的正則表達式是一個無效的表達式(就是表達式本身有問題)時,就會raise一個異常!我們來看看具體的案例吧:

上圖案例中我們可以看到,在編寫正則表達式中我們多寫了一個後括號,這導致執行結果報錯;而且是在其他所有案例執行之前,所以說明是在正則表達式編譯時期就報錯了。注意:這個異常一定是 正則表達式 本身是無效的,與要匹配的字符串無關!五、正則對象Pattern關於re模塊的常量、函數、異常我們都講解完畢,但是完全有必要再講講正則對象Pattern。1.  與re模塊 函數一致在re模塊的函數中有一個重要的函數 compile函數 ,這個函數可以預編譯返回一個正則對象,此正則對象擁有與re模塊相同的函數,我們來看看Pattern類的源碼。

既然是一致的,那到底該用re模塊 還是 正則對象Pattern ?而且,有些同學可能看過re模塊的源碼,你會發現其實compile函數 與 其他 re函數(search、split、sub等等) 內部調用的是同一個函數,最終還是調用正則對象的函數!

也就是說下面 兩種代碼寫法底層實現 其實是一致的:

re.search(pattern, text)
compile = re.compile(pattern)compile.search(text)

那還有必要使用compile函數 得到正則對象再去調用 search函數 嗎?直接調用re.search 是不是就可以?2. 官方文檔怎麼說關於到底該用re模塊 還是 正則對象Pattern ,官方文檔是否有說明呢?
官方文檔推薦:在多次使用某個正則表達式時推薦使用正則對象Pattern 以增加復用性,因為通過 re.compile(pattern) 編譯後的模塊級函數會被緩存!3. 實際測試又如何?上面官方文檔推薦我們在 多次使用某個正則表達式時使用正則對象,那實際情況真的是這樣的嗎?
豬哥編寫了兩個函數,一個使用re.search函數 另一個使用 compile.search函數 ,分別(不同時)循環執行count次(count從1-1萬),比較兩者的耗時!得出的結果豬哥繪製成折線圖:

得出的結論是:100次循環以內兩者的速度基本一致,當超出100次後,使用 正則對象Pattern 的函數 耗時明顯更短,所以比re模塊 要快!通過實際測試得知:Python 官方文檔推薦  多次使用某個正則表達式時使用正則對象函數 基本屬實!六、注意事項Python 正則表達式知識基本講解完畢,最後稍微給大家提一提需要注意的點。1.字節串 與 字符串模式和被搜索的字符串既可以是 Unicode 字符串 (str) ,也可以是8位字節串 (bytes)。但是,Unicode 字符串與8位字節串不能混用!2.r 的作用正則表達式使用反斜槓(』\』)來表示特殊形式,或者把特殊字符轉義成普通字符。而反斜槓在普通的 Python 字符串裡也有相同的作用,所以就產生了衝突。解決辦法是對於正則表達式樣式使用 Python 的原始字符串表示法;在帶有 『r』 前綴的字符串字面值中,反斜槓不必做任何特殊處理。3.正則查找函數 返回匹配對象查找一個匹配項(search、match、fullmatch)的函數返回值都是一個 匹配對象Match ,需要通過match.group() 獲取匹配值,這個很容易忘記。

另外還需要注意:match.group()match.groups() 函數的差別!4.重複使用某個正則如果要重複使用某個正則表達式,推薦先使用 re.compile(pattern)函數 返回一個正則對象,然後復用這個正則對象,這樣會更快!5.Python 正則面試筆試可能會遇到需要使用Python正則表達式,不過不會太難的,大家只要記住那幾個方法的區別,會正確使用,基本問題不大。文章所有內容精華豬哥已經整理成一份思維導圖:連結(或閱讀原文):https://pan.baidu.com/s/10MMpuf6Rcba-gvBo1oIzlw  密碼:y6z3

最後感謝大家閱讀,希望大家能學有所成~

相關焦點

  • python正則表達式,看完這篇文章就夠了...
    正則表達式這東西,你說它簡單它也簡單,你說它難吧,確實不容易。為什麼?這東西就是死記硬背的。背過了相關的語法,使用起來就so easy。但記不熟語法,就犯難了。網上關於python正則的帖子很多,我再去寫壓力比較大,儘可能的總結詳細一些吧!
  • Python 正則表達式
    最簡單的正則表達式就是普通字符串,可以匹配其自身。比如,正則表達式 『hello』 可以匹配字符串 『hello』。要注意的是,正則表達式並不是一個程序,而是用於處理字符串的一種模式,如果你想用它來處理字符串,就必須使用支持正則表達式的工具,比如 Linux 中的 awk, sed, grep,或者程式語言 Perl, Python, Java 等等。
  • 圖解正則表達式,這一篇就夠了
    所以,就讓我們揭開正則表達式的神秘面紗!如果你理解正則表達式,它會突然變成一個超快速和強大的工具……但你首先需要理解它,老實說,我覺得新手可能會對它望而生畏!讓我們從基礎開始。正則表達式(regex)是什麼?它們的用途是什麼?
  • Python正則表達式總結
    一、re模塊簡介聊到Python正則表達式的支持,首先肯定會想到re庫,這是一個Python處理文本的標準庫。標準庫的意思表示這是一個Python內置模塊,不需要額外下載,目前Python內置模塊大概有300個。
  • 萬字長文詳解Python正則表達式及re模塊
    這些都是正則表達式的運用。但是如果想查到一組限定的字符,比較原音字母(a, e, i, o, u),特殊字符(*, &, %, @)這怎麼弄呢?在正則表達式中使用[]將一組字符包裹起來,就到達了自己的需要,例如原音字符[aeiou],特殊字符[*&%@]即可完美的匹配任意一個!
  • 教你學習:Python-100-Days-12 正則表達式
    教你學習: Python-100-Days-12 正則表達式本項目是參考項目內容,進行個人理解,和原有項目有出入,如想了解詳情,請自行百度去搜索項目在編寫處理字符串的程序或網頁時,經常會有查找符合某些複雜規則的字符串的需要
  • python正則表達式
    微信公眾號:學點啥玩點啥小白友好型python正則表達式 1#第7章 模式匹配與正則表達式
  • 學習Python正則表達式
    Python中的正則表達式(re)就可以解決這個問題!正則表達式正則表達式是一個具有特殊字符的序列。它有助於檢查字符串中的每個字符,看它是否與某個模式匹配:哪些字符在什麼位置出現了多少次。result = re.findall(r』\d』, text)這將返回所有數字,但每個元素只有一個數字:['1', '0', '0', '1', '1', '1', '1', '2', '3', '4', '5', '6', '7']r-python原始字符串這裡,r表示python原始字符串。
  • 原創通俗易懂的Python的正則表達式,建議收藏
    正則表達式正則表達式是一個特殊的字符序列,由普通字符和元字符組成。元字符能幫助你方便的檢查一個字符串是否與某種模式匹配。正則表達式應用的場景也非常多。常見的比如:搜尋引擎的搜索、爬蟲結果的匹配、文本數據的提取等等都會用到,所以掌握甚至精通正則表達式是一個硬性技能,非常必要。
  • 妙用正則表達式--Python中的re模塊
    Python中的re模塊可以方便地引入正則表達式。利用正則表達式,我們可以對文本內容進行精確快捷地匹配和提取。與Stata相比,正則表達式的元字符是通用的,不同的是函數。re庫中有若干個函數各司其職,在上一篇推文《Python標準庫re:正則表達式》中我們介紹了re庫中的三個常用函數,現在小編將從實用的角度再介紹幾個常用的函數。
  • Python正則表達式:特殊符號和字符
    正表達式為高級的文本模式匹配,抽取,與/或文本形式的搜索和替換功能提供了基礎。簡而言之,正則表達式(簡稱regex)是由一些字符和特殊符號組成的字符串,它描述了模式的重複或者表達多個字符。python通過標準庫中的re模塊來支持正則表達式。
  • Python正則表達式很難?一篇文章搞定他,不是我吹!
    正則表達式語法1.1 字符與字符類學習python中有什麼不懂的地方,小編這裡推薦加小編的python學習群:696541369有任何不懂的都可以在裡面交流,還有很好的視頻教程pdf學習資料,大家一起學習交流!1 特殊字符:.^$?
  • Python3爬蟲(4)--python正則表達式詳細版
    等等,在python中,這些都可以用正則表達式處理函數進行處理。re 模塊使 Python 語言擁有全部的正則表達式功能。函數語法:re.search(pattern, string, [flags])re.match只匹配字符串的開始,如果字符串開始不符合正則表達式,則匹配失敗,函數返回None;而re.search匹配整個字符串,直到找到一個匹配。所以實際應用往往使用re.search()函數。pattern:匹配的正則表達式(參考後面的正則表達式匹配模式附件)。
  • Python正則表達式入門到入魔
    2、20世紀50年代一位名叫Stephen Kleene的數學科學家發表了一篇題目是《神經網事件的表示法》的論文,利用稱之為正則集合的數學符號來描述此模型,引入了正則表達式的概念。正則表達式被作為用來描述其稱之為「正則集的代數」的一種表達式,因而採用了「正則表達式」這個術語。
  • python正則表達式使用方法說明
    曾光紅/文 (同步發布豆瓜網)一、導入re庫python使用正則表達式要導入re庫。import re在re庫中。正則表達式通常被用來檢索查找、替換那些符合某個模式(規則)的文本。2.星號「*」一個星號可以表示它前面的一個子表達式(普通字符、另一個或幾個正則表達式符號)0次到無限次。3.問號「?」問號表示它前面的子表達式0次或者1次。注意,這裡的問號是英文問號。
  • 【Python】一文讀懂Python正則表達式常用用法
    最簡單的正則表達式就是普通字符串,可以匹配其自身。比如,正則表達式 『hello』 可以匹配字符串 『hello』。要注意的是,正則表達式並不是一個程序,而是用於處理字符串的一種模式,如果你想用它來處理字符串,就必須使用支持正則表達式的工具,比如 Linux 中的 awk, sed, grep,或者程式語言 Perl, Python, Java 等等。
  • Python中正則表達式模塊詳解
    用來處理字符串,對字符串進行檢索和替換,另外正則在python爬蟲的應用也是相當廣泛!
  • Python之re模塊方法詳解(正則表達式)
    學習re模塊首先要對python正則表達式要了解,正則表達式是一個特殊的字符序列,它能幫助你方便的檢查一個字符串是否與某種模式匹配
  • Python正則表達式
    什麼是正則表達式?正則表達式(Regular Expression)通常被用來檢索、替換那些符合某個模式(規則)的文本。此處的Regular即是規則、規律的意思,Regular Expression即「描述某種規則的表達式」之意。
  • Python:正則表達式基本符號總結
    說明:如果需要匹配的字符是正則表達式中的特殊字符,那麼可以使用\進行轉義處理,例如想匹配小數點可以寫成\.就可以了,因為直接寫.會匹配任意字符;同理,想匹配圓括號必須寫成和。在python中,如果使用正則表達式的話,需要導入re模塊,re模塊是一個內置模塊,直接import就可以使用,下面是re模塊中的核心函數。