詳解 Python3 正則表達式(一)

来源:http://www.cnblogs.com/fanfannotplay/archive/2017/05/28/6915845.html
-Advertisement-
Play Games

本文翻譯自:https://docs.python.org/3.4/howto/regex.html 博主對此做了一些批註和修改 ^_^ 正則表達式介紹 正則表達式(Regular expressions 也稱為 REs,或 regexes 或 regex patterns)本質是一個微小的且高度專 ...


本文翻譯自:https://docs.python.org/3.4/howto/regex.html

博主對此做了一些批註和修改 ^_^

正則表達式介紹

正則表達式(Regular expressions 也稱為 REs,或 regexes 或 regex patterns)本質是一個微小的且高度專業化的編程語言。它被嵌入到 Python 中,並通過 re 模塊提供給程式員使用。使用正則表達式,你需要指定一些規則來描述那些你希望匹配的字元串集合。這些字元串集合可能包含英語句子、e-mail 地址、TeX 命令,或任何你想要的東東。

正則表達式模式被編譯成一系列的位元組碼,然後由一個 C 語言寫的匹配引擎所執行。對於高級的使用,你可能需要關註匹配引擎是如何執行給定的 RE,並通過一定的方式來編寫 RE,以便產生一個可以運行得更快的位元組碼。本文暫不講解優化的細節,因為這需要你對匹配引擎的內部機制有一個很好的理解。但本文的例子均是符合標準的正則表達式語法。

批註:Python 的正則表達式引擎是用 C 語言寫的,所以效率是極高的。另,所謂的正則表達式,這裡說的 RE,就是上文我們提到的 “一些規則”。

正則表達式語言相對較小,並且受到限制,所以不是所有可能的字元處理任務都可以使用正則表達式來完成。還有一些特殊的任務,可以使用正則表達式來完成,但是表達式會因此而變得非常複雜。在這種情況下,你可能通過自已編寫 Python 代碼來處理會更好些;儘管 Python 代碼比一個精巧的正則表達式執行起來會慢一些,但可能會更容易理解。

批註:這可能是大家常說的 “醜話說在前” 吧,大家別管它,正則表達式非常優秀,它可以處理你 98.3% 的文本任務,一定要好好學哦~~~~

簡單的模式

我們將從最簡單的正則表達式學習開始。由於正則表達式常用於操作字元串,因此我們從最常見的任務下手:字元匹配。

字元匹配

大多數字母和字元會匹配它們自身。舉個例子,正則表達式 Fanfan 將完全匹配字元串 “Fanfan”(你可以啟用不區分大小模式,這將使得 Fanfan 可以匹配 “FANFAN” 或 “fanfan”,我們會在後邊討論這個話題)。

當然這個規則也有例外,有少數特殊的字元我們稱之為元字元(metacharacter),它們並不能匹配自身,它們定義了字元類、子組匹配和模式重覆次數等。本文用很大的篇幅專門討論了各種元字元及其作用。

下邊是元字元的完整列表(我們將在後邊逐一講解):

. ^ $ * + ? {} [] \ | ()

 批註:如果沒有這些元字元,正則表達式就變得跟字元串的 find() 方法一樣平庸了......

我們先來看下方括弧 [ ],它們指定一個字元類用於存放你需要匹配的字元集合。可以單獨列出需要匹配的字元,也可以通過兩個字元和一個橫桿 - 指定匹配的範圍。例如 [abc] 會匹配字元 a,b 或 c;[a-c] 可以實現相同功能。後者使用範圍來表示與前者相同的字元集合。如果你想只匹配小寫字母,你的 RE 可能寫成 [a-z]。

需要註意的一點是:元字元在方括弧中不會觸發 “特殊功能”,在字元類中,它們只匹配自身。例如 [akm$] 會匹配任何字元 'a','k','m' 或 '$',‘$’ 是一個元字元,但在方括弧它不表示特殊含義,它只匹配 '$' 字元本身。

你還可以匹配方括弧中未列出的所有其它字元,做法是在類的開頭添加一個脫字元號 ^,例如 [^5] 會匹配除了 '5' 之外的任何字元。

或許最重要的元字元當屬反斜杠 \ 了,跟 Python 的字元串規則一樣,如果在反斜杠後邊緊跟著一個元字元,那麼元字元的 “特殊功能” 也不會被觸發。例如你需要匹配符號 [\,你可以在它們前面加上一個反斜杠,以消除它們的特殊功能:\[\\

反斜杠後邊跟一些字元還可以表示特殊的意義,例如表示十進位數字,表示所有的字母或者表示非空白的字元集合。

批註:反斜杠真牛逼,反斜杠後邊跟元字元去除特殊功能,反斜杠後邊跟著普通字元實現特殊功能。

讓我們來舉個例子:\w 匹配任何單詞字元。如果正則表達式以位元組的形式表示,這相當字元類 [a-zA-Z0-9_];如果正則表達式是一個字元串,\w 會匹配所有 Unicode 資料庫(unicodedata 模塊提供)中標記為字母的字元。你可以在編譯正則表達式的時候,通過提供 re.ASCII 表示進一步限制 \w 的定義。

批註:re.ASCII 標誌使得 \w 只能匹配 ASCII 字元,不要忘了,Python3 是 Unicode 的。

下邊列舉一些反斜杠加字元構成的特殊含義:

特殊字元 含義
\d 匹配任何十進位數字,相當於類[0-9]
\D  與 \d 相反,匹配任何非十進位數字的字元,相當於 [^0-9]
\s  匹配任何空白字元(包含空格、換行符、製表符等),相當於類 [\t\n\r\f\v]
\S  與 \s 相反,匹配任何非空白字元,當相於類 [^\t\n\r\f\v]
\w  匹配任何單詞字元,見上方解釋
\W  與 \w 相反
\b  匹配單詞的開始或結束
\B  與 \b 相反

它們可以包含在一個字元類中,並且一樣擁有特殊含義。例如 [\s,.] 是一個字元類,它將匹配任何空白字元(/s 的特殊含義),',' 或 ‘.’ 。

最後我們要講的一個元字元是 .,它匹配除了換行符以外的任何字元。如果設置了 re.DOTALL 標誌,. 將匹配包括換行在內的任何字元。

重覆的事情

使用正則表達式能夠輕鬆的匹配不同的字元集合,但 Python 字元串現有的方法卻無法實現。然而,如果你認為這是正則表達式的唯一優勢,那你就 too young too native 了。正則表達式有另一個強大的功能,就是你可以指定 RE 部分被重覆的次數。

我們來看看 * 這個元字元,當然它不是匹配 '*' 字元本身(我們說過元字元都是有特殊能力的),它用於指定前一個字元匹配零次或者多次。

例如 ca*t 將匹配 ct(0 個字元 a),cat(1 個字元 a),caaat(3 個字元 a),等等。需要註意的是,由於受到 C 語言的 int 類型大小的內部限制,正則表達式引擎會限制字元 'a' 的重覆個數不超過 20 億個;不過,通常我們工作也用不到那麼大的數據。

正則表達式預設的重覆規則是貪婪的,當你重覆匹配一個 RE 時,匹配引擎會嘗試儘可能多的去匹配。直到 RE 不匹配或者到了結尾,匹配引擎就會回退一個字元,然後再繼續嘗試匹配。

我們通過例子一步步的給大家講解什麼叫 “貪婪”:先考慮一下表達式 a[bcd]*b,首先需要匹配字元 'a',然後零個到多個 [bcd],最後以 'b' 結尾。那現在想象一下,這個 RE 匹配字元串 abcbd 會怎樣?

步驟 匹配 說明
1 a 匹配 RE 的第一個字元 'a'
2 abcbd 引擎在符合規則的情況下儘可能地匹配 [bcd]*,直到該字元串的結尾
3 失敗 引擎嘗試匹配 RE 最後一個字元 ‘b’,但當前位置已經是字元串的結尾,所以失敗告終
4 abcb 回退,所以 [bcd]* 匹配少一個字元
5 失敗 再一次嘗試匹配 RE 最後一個字元 'b',但字元串最後一個字元是 'b',所以失敗告終
6 abc 再次回退,所以 [bcd]* 這次只匹配 'bc'
7 abcb 再一次嘗試匹配這符 'b',這一次字元串當前位置指向的字元正好是 'b',匹配成功

最終,RE 匹配的結果是 abcb 。

批註:正則表達式預設的匹配規則是貪婪的,後邊有教你如何使用非貪婪的方法匹配。

另一個實現重覆的元字元是 +,用於指定前一個字元匹配一次或者多次。

要特別註意 *+ 的區別:* 匹配的是零次或者多次,所以被重覆的內容可能壓根兒不會出現;+ 至少需要出現一次。例如 ca+t 會匹配 cat 和 caaat,但不會匹配 ct 。

還有兩個表示重覆的元字元,其中一個是問號 ?,用於指定前一個字元匹配零次或者一次。你可以這麼想,它的作用就是把某種東西標誌位可選的。

最靈活的應該是元字元 {m,n}(m 和 n 都是十進位數),上邊講到的幾個元字元都可以使用它來表達,它的含義是前一個字元必須匹配 m 次到 n 次之間。例如 a/{1,3}b 會匹配 a/b,a//b 和 a///b 。但不會匹配 ab(沒有斜杠);也不會匹配 a////b(斜杠超過三個)。

你可以省略 m 或者 n,這樣的話,引擎會假定一個合理的值代替。省略 m,將被解釋為下限 0;省略 n 則會被解釋為無窮大(事實上是上邊我們提到的 20 億)。

批註:如果是 {,n} 相當於 {0,n};如果是 {m,} 相當於 {m,正無窮};如果是 {n},則是重覆前一個字元 n 次。另外還有一個超容易出錯的是寫成 {m, n},看著挺美,但註意,正則表達式裡邊不能隨意添加空格,不然會改變原來的含義。

最後,其實 *+? 都可以使用 {m,n} 來代替。{0,} 跟 * 是一樣的;{1,} 跟 + 是一樣的;{0,1} 跟 ? 是一樣的。不過還是鼓勵大家記住並使用 *+?,因為這些字元更短並且更容易閱讀。

批註:還有一個原因是匹配引擎對 * + ? 做了優化,效率要更高些。

(本文完)

下一篇:詳解 Python3 正則表達式(二)

如果你喜歡這篇文章,請通過下方「評論」給我鼓勵哦 ^_^


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • eclipse啟動時彈出Failed to create the Java Virtual Machine 一、現象 今天裝eclipse的時候出現Failed to create the Java Virtual Machine 的錯誤。 錯誤圖片如下: 二、出錯原因 把錯誤提示翻譯一下,就是“無 ...
  • Ctrl+1 快捷修複 Ctrl+D 快捷刪除 shift+enter 跳過本行開始下一行 Ctrl+F11 快速運行 Alt+↑/↓ 快速移動行 Ctrl+Alt+↑/↓ 快速複製行 Ctrl+M 視窗最大化 Alt+/ 自動補全 代碼區域右鍵 選中preferences →Java →edito ...
  • 國際化英文單詞為:Internationalization,又稱I18N,I為因為單詞的第一個字母,18為這個單詞的長度,而N代表這個單詞的最後一個字母。國際化又稱本地化(Localization,L10N)。 Java國際化主要通過如下3個類完成 java.util.ResourceBundle:... ...
  • Socket簡介: Socket稱為“套接字”,描述IP地址和埠。在Internet上的主機一般運行多個服務軟體,同時提供幾種服務,每種服務都打開一個Socket,並綁定在一個埠上,不同的埠對應於不同的服務。Socket和ServerSocket類位於java.net包中。ServerSock ...
  • 1、在(x1,y1) (x2,y2)兩點構成的線段(不含端點)上有gcd(x1-x2,y1-y2)-1個整點。 2、兩個longlong相乘後%一個數可以以下述方法避免高精度 3、$\sum\limits_{i=1}^n i^2=\frac{n(n+1)(n+2)}{6}$ 4、函數前面加inlin ...
  • 在日常的開發中我們經常會碰到對文件的操作,在java中對文件的操作都在java.io包下,這個包下的類有File、inputStream、outputStream、FileInputStream、FileOutputStream、reader、writer、FileReader、FileWriter ...
  • 1.簡介 JDBC(Java DataBase Connectivity) 是一種可用於執行SQL語句的Java API,是一套面向對象的應用程式介面, 統一了資料庫的訪問方式,資料庫廠商提供了實現介面的類,稱為‘驅動程式’。因此JDBC並不能直接訪問資料庫, 需要依賴資料庫廠商提供的JDBC驅動程 ...
  • python多進程和多線程誰更快 python3.6 threading和multiprocessing 四核+三星250G 850 SSD 自從用多進程和多線程進行編程,一致沒搞懂到底誰更快。網上很多都說python多進程更快,因為GIL(全局解釋器鎖)。但是我在寫代碼的時候,測試時間卻是多線程更 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...