python正則r的作用_Python正則表達式,這一篇就夠了!

原標題: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是內置模塊,所以不需要再下載,使用時直接引入即可:

import re

re模塊官方文檔:https://docs.python.org/zh-cn/3.8/library/re.html

re模塊庫源碼:https://github.com/python/cpython/blob/3.8/Lib/re.py

二、re模塊常量

常量即表示不可更改的變量,一般用于做標記。

re模塊中有9個常量,常量的值都是int類型!

上圖我們可以看到,所有的常量都是在 RegexFlag枚舉類 來實現,這是在Python 3.6做的改版。在Python 3.6以前版本是直接將常量寫在re.py中,使用枚舉的好處就是方便管理和使用!

下面我們來快速學習這些常量的作用及如何使用他們,按常用度排序!

1. IGNORECASE

語法: re.IGNORECASE 或簡寫為 re.I

作用: 進行忽略大小寫匹配。

代碼案例:

在默認匹配模式下 大寫字母B 無法匹配 小寫字母b ,而在 忽略大小寫 模式下是可以的。

2. ASCII

語法: re.ASCII 或簡寫為 re.A

作用: 顧名思義,ASCII表示ASCII碼的意思,讓 \w , \W , \b , \B , \d , \D , \s 和 \S只匹配ASCII,而不是Unicode。

代碼案例:

在默認匹配模式下 \w+ 匹配到了所有字符串,而在 ASCII 模式下,只匹配到了a、b、c(ASCII編碼支持的字符)。

注意:這只對字符串匹配模式有效,對字節匹配模式無效。

3. DOTALL

語法: re.DOTALL 或簡寫為 re.S

作用: DOT表示 . ,ALL表示所有,連起來就是 . 匹配所有,包括換行符 \n 。 默認模式下 . 是不能匹配行符 \n 的 。

代碼案例:

在默認匹配模式下 . 并沒有匹配換行符 \n ,而是將字符串分開匹配;而在 re.DOTALL 模式下,換行符 \n 與字符串一起被匹配到。

注意: 默認匹配模式下 . 并不會匹配換行符 \n 。

4. MULTILINE

語法: re.MULTILINE 或簡寫為 re.M

作用: 多行模式,當某字符串中有換行符 \n ,默認模式下是不支持換行符特性的,比如:行開頭 和 行結尾,而多行模式下是支持匹配行開頭的。

代碼案例:

正則表達式中 ^ 表示匹配行的開頭,默認模式下它只能匹配字符串的開頭;而在多行模式下,它還可以匹配 換行符 \n 后面的字符。

注意:正則語法中 ^ 匹配行開頭、 \A 匹配字符串開頭,單行模式下它兩效果一致,多行模式下 \A 不能識別 \n 。

5. VERBOSE

語法: re.VERBOSE 或簡寫為 re.X

作用: 詳細模式,可以在正則表達式中加注解!

代碼案例:

默認模式下并不能識別正則表達式中的注釋,而詳細模式是可以識別的。

當一個正則表達式十分復雜的時候,詳細模式或許能為你提供另一種注釋方式,但它不應該成為炫技的手段,建議謹慎考慮后使用!

6.LOCALE

語法: re.LOCALE 或簡寫為 re.L

作用: 由當前語言區域決定 \w , \W , \b , \B 和大小寫敏感匹配,這個標記只能對byte樣式有效。 這個標記官方已經不推薦使用 ,因為語言區域機制很不可靠,它一次只能處理一個 “習慣”,而且只對8位字節有效。

注意: 由于這個標記官方已經不推薦使用,而且豬哥也沒使用過,所以就不給出實際的案例!

7.UNICODE

語法: re.UNICODE 或簡寫為 re.U

作用: 與 ASCII 模式類似,匹配unicode編碼支持的字符,但是 Python 3 默認字符串已經是Unicode,所以有點冗余。

8. DEBUG

語法: re.DEBUG

作用: 顯示編譯時的debug信息。

代碼案例:

雖然debug模式下確實會打印編譯信息,但豬哥并不理解這是什么語言 以及表達的含義, 希望了解的朋友能不吝賜教。

9.TEMPLATE

語法: re.TEMPLATE 或簡寫為 re.T

作用: 豬哥也沒搞懂TEMPLATE的具體用處,源碼注釋中寫著: disable backtracking(禁用回溯),有了解的同學可以留言告知!

10. 常量總結

9個常量中,前5個(IGNORECASE、ASCII、DOTALL、MULTILINE、VERBOSE)有用處,兩個(LOCALE、UNICODE)官方不建議使用、兩個(TEMPLATE、DEBUG)試驗性功能,不能依賴。

常量在re常用函數中都可以使用,查看源碼可得知。

常量可疊加使用,因為常量值都是2的冪次方值,所以是可以疊加使用的,疊加時請使用 | 符號,請勿使用 + 符號!

最后來一張思維導圖總結一下re模塊中的常量吧, 需要高清圖或者xmind文件的同學可在文章末尾

獲取。

三、re模塊函數

re模塊有12個函數,豬哥將以功能分類來講解;這樣更具有比較性,同時也方便記憶。

1.查找一個匹配項

查找并返回一個匹配項的函數有3個: search、match、fullmatch ,他們的區別分別是:

search : 查找任意位置的匹配項

match : 必須從字符串開頭匹配

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

我們再來根據實際的代碼案例比較:

案例1:

案例1中 search函數 是在字符串中任意位置匹配,只要有符合正則表達式的字符串就匹配成功,其實有兩個匹配項,但search函數值返回一個。

而 match函數 是要從頭開始匹配,而字符串開頭多了個字母 a ,所以無法匹配, fullmatch函數 需要完全相同,故也不匹配!

案例2:

案例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函數 ,他們功能類似!

先來看看 sub函數 的用法:

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函數

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正則表達式,不過不會太難的,大家只要記住那幾個方法的區別,會正確使用,基本問題不大。

近期有很多朋友通過私信咨詢有關Python學習問題。為便于交流,點擊藍色自己加入討論解答資源基地返回搜狐,查看更多

責任編輯:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/370684.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/370684.shtml
英文地址,請注明出處:http://en.pswp.cn/news/370684.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

服務器微信了早上好,每天早上好的問候語 微信早安問候語合集66句

1、沒有傘的孩子,必須努力奔跑!早安!2、你不能改變過去,但你可以改變未來。早安!3、堅持了才叫夢想,放棄了就只是妄想。早安!4、忘掉失敗,不過要牢記失敗中的教訓。早安!…

如何得到某個文件的舊版本

下載某個文件的舊版本 如果想要得到某個文件的舊版本,只需在該文件上單擊右鍵,選擇Updata to revision…即可。 系統會提示輸入版本號。 例如要下載soc_1的第五個版本,只需填入5即可。如圖7。 查看完版本5的文件后,如果想在此回到…

Google Guava EventBus和Java 7 WatchService用于事件編程

這篇文章將介紹如何使用Guava EventBus將更改發布到Java 7 WatchService檢測到的目錄或子目錄中。 Guava EventBus是向應用程序添加發布/訂閱通信的好方法。 Java 7 java.nio.file軟件包中新增的WatchService用于監視目錄中的更改。 由于EventBus和WatchService已在以前的文章中…

Bootstrap-table 部分瀏覽器顯示不出來

一、問題 近日,寫了一個ASP.Net項目,但是bootstrap-table在別人的電腦上顯示不出來,在自己的電腦上能顯示,有些瀏覽器也是能顯示,但部分瀏覽器就是顯示不出來。找了很多原因,最后有個老師和我說是內核版本的…

DBMS-基本概念

文件處理系統(file-processing system)的主要弊端: 數據冗余和不一致(data redundancy and inconsistency)、數據訪問困難(difficulty in accessing data)、數據孤立(data isolation…

python多大孩子可以學_孩子學編程最佳年齡是多大

兒童編程教育已經悄悄地掀起了編程低齡化的熱浪。但是很多人會疑惑,到底孩子學編程最佳年齡是多少呢?下面小編就為大家解答一下。孩子學編程最佳年齡 首先,孩子的學習黃金時期是非常重要的。從6歲開始,大多數孩子都可以掌握對基本…

上傳文件到華為云云服務器,上傳文件到云服務器

上傳文件到云服務器 內容精選換一換登錄Windows操作系統的彈性云服務器時,需使用密碼方式登錄。因此,用戶需先根據創建彈性云服務器時使用的密鑰文件,獲取該彈性云服務器初始安裝時系統生成的管理員密碼(Administrator帳戶或Cloudbase-init設…

JUnit規則

第一次偶然發現JUnit Rule批注時,我對此概念有些惱火。 在測試用例中擁有一個公共領域似乎有些奇怪,因此我不愿意定期使用它。 但是一段時間后,我習慣了這一點,事實證明,規則可以通過多種方式簡化編寫測試的過程。 這篇…

微pe工具箱是微軟的嗎_微PE工具箱V2.0更新10內核

本帖最后由 韋小寶2 于 2017-3-22 21:26 編輯微PE工具箱V2.0發布更新了,鏈接:http://pan.baidu.com/s/1c9whpO 轉載自無憂論壇 07年,第一個XP內核通用PE工具箱發布。17年,第一個WIN10內核的微PE工具箱就此誕生。64位純內核&#x…

jq實現輪播圖

之前設計了一個校團委網站,里面有一個輪播圖效果,上網后查看了許多方法,覺得下面這個方法最為適用,記錄下來 js代碼: $(document).ready(function () {//無縫切換輪播var i 0;//索引var clone $(".banner .imgL…

關于圖片預加載的思考

引子&#xff1a; 很多時候&#xff0c;我們在寫html頁面的時候&#xff0c;當需要在頁面中加入圖片時&#xff0c;我們很自然地把圖片直接用<img>標簽放在了<body>里面&#xff0c;這本來是沒有多大問題的。 但是當圖片數量很多的時候&#xff0c;問題就來了。H…

oracle安裝中桌面模式與服務器模式的去別

桌面模式只能本機使用。 服務器模式可以在網絡中使用&#xff0c;也就是網絡中的其他服務器可以使用。 所以安裝時&#xff0c;如果是生產環境肯定是服務器模式。一般也都是服務器模式。 轉載于:https://www.cnblogs.com/zhjx0521/p/7803691.html

python不能創建字典的是_用Python創建帶有重復鍵的字典

用Python創建帶有重復鍵的字典 我有以下列表&#xff0c;其中包含重復的具有不同值的汽車注冊號。 我想將其轉換為字典&#xff0c;該字典接受汽車登記號的多個鍵。 到目前為止&#xff0c;當我嘗試將列表轉換為字典時&#xff0c;它消除了鍵之一。 如何制作具有重復鍵的字典&a…

python中int是什么的縮寫_python中int是什么類型

python中的基本數據類型1:雖然python中的變量不需要聲明&#xff0c;但使用時必須賦值整形變量浮點型變量字符型2:可以一個給多個變量賦值&#xff0c;也可以多個給多個變量賦值3:python3中有6個標準數據類型Number(數字)*True1*False0*數值的除法(/)總是返回一個浮點數&#x…

redis cli命令

redis安裝后&#xff0c;在src和/usr/local/bin下有幾個以redis開頭的可執行文件&#xff0c;稱為redis shell&#xff0c;這些可執行文件可做很多事情。 可執行文件作用redis-server 啟動redisredis-cliredis命令行工具redis-benchmark基準測試工具redis-check-aofAOF持久化文…

高級ZK:異步UI更新和后臺處理–第2部分

介紹 在第1部分中&#xff0c;我展示了如何在ZK應用程序中使用服務器推送和線程來執行后臺任務。 但是&#xff0c;這個簡單的示例具有一個重大缺陷&#xff0c;這使其對于實際應用程序而言是一種不好的方法&#xff1a;它為每個后臺任務啟動了一個新線程。 JDK5引入了Execut…

css清除浮動的原理

最近學習css發現了高度塌陷時候要清除浮動,為了理解清楚浮動原理,網上找了不少資料,發現都寫的不是很清楚,而且都是一模一樣的內容,我在里分享一下我對清楚浮動原理的理解, 如果你已經很了解什么是浮動和浮動的效果你可以直接跳轉到三.如何清除浮動(重點)閱讀 一.什么是浮動首…

SpringBoot03 項目熱部署

1 問題 在編寫springBoot項目時&#xff0c;經常需要修改代碼&#xff1b;但是每次修改代碼后都需重新啟動&#xff0c;修改的代碼才會生效 2 這么實現IDEA能夠像Eclipse那樣保存過后就可以自動進行刷新呢 將springBoot項目進行熱部署即可 3 如何實現SpringBoot項目的熱部署01 …

STM32實現流水燈

led.c #include"led.h"void Led_Init(void) {GPIO_InitTypeDef GPIO_VALUE; //???RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//???GPIO_VALUE.GPIO_ModeGPIO_Mode_Out_PP;//???? ????GPIO_VALUE.GPIO_PinGPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_…

jacob 報錯 Can't co-create object

問題&#xff1a;開始時一切正常&#xff0c;后來什么都沒該&#xff0c;出現Cant co-create object報錯&#xff0c;即是創建不了ActiveXComponent wdnew ActiveXComponent("Word.Application"); 偶爾發現任務管理器中word進程居然達到10個&#xff0c;而我沒有打開…