代碼詳解:Python正則表達式的終極使用指南

2021-01-08 讀芯術

全文共8032字,預計學習時長16分鐘

處理文本數據的一個主要任務就是創建許多以文本為基礎的特性。

人們可能想要在文本中找出特定格式的內容,比如找出存在於文本中的電子郵件,或者大型文本中的電話號碼。

雖然想要實現上述功能聽起來很繁瑣,但是如果使用Python正則表達式模塊,就可以使這一操作更加簡單。

假設要在一篇特定的文章中找出標點符號的數量。以狄更斯的作品文本為例。

你通常會怎麼做?

最簡單的方法如下:

target = [';','.',',','–']

string = "It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way – in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only."

num _ points = 0

num_puncts = 0

for punct in target:

if punct in string:

num_puncts+=string.count(punct)print(num_puncts)

-

19

如果沒有可支配的re模塊,那就要用到上面的代碼。但如果有re模塊,則只需兩行代碼:

import re

pattern = r"[;.,–]"

print(len(re.findall(pattern,string)))

-

19

本文討論的是最常用的正則表達式模式,以及一些經常使用的正則表達式函數。

什麼是正則表達式?

簡而言之,正則表達式(regex)用於探索給定字符串中的固定模式。

我們想找到的模式可以是任何東西。

可以創建類似於查找電子郵件或手機號碼的模式。還可以創建查找以a開頭、以z結尾的字符串的模式。

在上面的例子中:

import re

pattern = r'[,;.,–]'

print(len(re.findall(pattern,string)))

我們想找出的模式是 r』[,;.,–]』。這個模式可找出想要的4個字符中的任何一個。regex101是一個用於測試模式的工具。將模式應用到目標字符串時,呈現出以下界面。

如圖所示,可以在目標字符串中根據需要找到,;.,–。

每當需要測試正則表達式時,都會用到上面的工具。這比一次又一次運行python要快得多,調試也容易得多。

現在我們已經可以在目標字符串中找到這些模式,那麼如何真正創建這些模式呢?

創建模式

使用正則表達式時,首先需要學習的是如何創建模式。

接下來將對一些最常用的模式進行逐一介紹。

可以想到最簡單的模式是一個簡單的字符串。

pattern = r'times'

string = "It was the best of times, it was the worst of times."

print(len(re.findall(pattern,string)))

但這並不是很有用。為了幫助創建複雜的模式,正則表達式提供了特殊的字符/操作符。下面來逐個看看這些操作符。請等待gif加載。

1.[]操作符

這在第一個例子中使用過,可用於找到符合這些方括號中條件的一個字符。

[abc]-將查找文本中出現的所有a、b或c

[a-z]-將查找文本中出現的所有從a到z的字母

[a-z0–9A-Z]-將查找文本中出現的所有從A到Z的大寫字母、從a到z的小寫字母和從0到9的數字。

可以很容易地在Python中運行下列代碼:

pattern = r'[a-zA-Z]'

string = "It was the best of times, it was the worst of times."

print(len(re.findall(pattern,string)))

除了.findall,正則表達式還有很多其他功能,稍後會涉及到。

2.點算符

點運算符(.) 用於匹配除換行符以外的任何字符。

運算符最大的優點是,它們可以結合使用。

例如,想在字符串中找出以小d或大寫D開頭,以字母e結尾,包含6個字母的子字符串。

3.一些元序列

在使用正則表達式時,一些模式會經常被用到。因此正則表達式為這些模式創建了一些快捷方式。最常用的快捷方式如下:

\w,匹配任何字母、數字或下劃線。相當於[a-zA-Z0–9_]

\W,匹配除字母、數字或下劃線以外的任何內容。

\d,匹配任何十進位數字。相當於[0–9]。

\D,匹配除十進位數字以外的任何數字。

4.加號和星形運算符

點算符只是用於獲取任何字符的單個實例。如果想找出更多實例要怎麼做呢?

加號+用於表示最左邊字符的一個或多個實例。

星號*用於表示最左邊字符的0個或多個實例。

例如,如果想找出所有以d開頭,以e結尾的子字符串,d和e之間可以沒有也可以有多個字符。我們可以用:d\w*e

如果想找出所有以d開頭,以e結尾的子字符串,在d和e之間至少有一個字符,我們可以用:d\w+e

還可以使用更為通用的方法:用{}

\w{n} - 重複\w 正好n次。

\w{n,} - 重複\w至少n次,或者更多次。

\w{n1, n2} - 重複 \w 至少n1次,但不超過n2次。

5.^插入符號和$美元符號。

^插入符號匹配字符串的開始,而$美元符號則匹配字符串的結尾。

6.單詞邊界

這是一個重要的概念。

有沒有注意到,在上面的例子中,總是匹配子字符串,而不是匹配單詞?

如果想找出所有以d開頭的單詞呢?

可以使用d\w*模式嗎?下面用網絡工具來試一試吧。

正則表達式函數

目前為止,只使用了 re包中的findall 函數,其實還有很多其他函數。下面來逐個介紹。

1. findall

上面已經使用了 findall。這是我最常使用的一個。下面來正式認識一下這個函數吧。

輸入:模式和測試字符串

輸出:字符串列表。

#USAGE:

pattern = r'[iI]t'

string = "It was the best of times, it was the worst of times."

matches = re.findall(pattern,string)

for match in matches:

print(match)

It

it

2.搜索

輸入:模式和測試字符串

輸出:首次匹配的位置對象。

#USAGE:

pattern = r'[iI]t'

string = "It was the best of times, it was the worst of times."

location = re.search(pattern,string)

print(location)

<_sre.SRE_Match object; span=(0, 2), match='It'>

可以使用下面編程獲取該位置對象的數據:

print(location.group())

'It'

3.替換

這個功能也很重要。當使用自然語言處理程序時,有時需要用X替換整數,或者可能需要編輯一些文件。任何文本編輯器中的查找和替換都可以做到。

輸入:搜索模式、替換模式和目標字符串

輸出:替換字符串

string = "It was the best of times, it was the worst of times."

string = re.sub(r'times', r'life', string)

print(string)

It was the best of life, it was the worst of life.

案例研究

正則表達式在許多需要驗證的情況下都會用到。我們可能會在網站上看到類似這樣的提示:「這不是有效的電子郵件地址」。雖然可以使用多個if和else條件來編寫這樣的提示,但正則表達式可能更具優勢。

1.PAN編號

在美國,SSN(社會安全號碼)是用於稅務識別的號碼,而在印度,稅務識別用的則是 PAN號碼。PAN的基本驗證標準是:上面所有的字母都必須大寫,字符的順序如下:

<char><char><char><char><char><digit><digit><digit><digit><char>

那麼問題是:

「ABcDE1234L」是有效的PAN號碼嗎?

如果沒有正則表達式,該如何回答這個問題呢?可能會編寫一個for循環,並進行遍歷搜索。但如果用正則表達式,那就像下面這樣簡單:

match=re.search(r』[A-Z]{5}[0–9]{4}[A-Z]』,'ABcDE1234L')

if match:

print(True)

else:

print(False)

False

2.查找域名

有時我們必須從一個龐大的文本文檔中找出電話號碼、電子郵件地址或域名等。

例如,假設有以下文本:

<div style="list-style-type: decimal;">

<ol>

<li id="cite_note-1"><span><b>^ ["Train (noun)"](http://www.askoxford.com/concise_oed/train?view=uk). <i>(definition – Compact OED)</i>. Oxford University Press<span>. Retrieved 2008-03-18</span>.</span><span title="ctx_ver=Z39.88-2004&rfr_id=info%3Asid%2Fen.wikipedia.org%3ATrain&rft.atitle=Train+%28noun%29&rft.genre=article&rft_id=http%3A%2F%2Fwww.askoxford.com%2Fconcise_oed%2Ftrain%3Fview%3Duk&rft.jtitle=%28definition+%E2%80%93+Compact+OED%29&rft.pub=Oxford+University+Press&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Ajournal"><span style="display:none;"> </span></span></span></li>

<li id="cite_note-2"><span><b>^</b></span> <span><span>Atchison, Topeka and Santa Fe Railway (1948). <i>Rules: Operating Department</i>. p. 7.</span><span title="ctx_ver=Z39.88-2004&rfr_id=info%3Asid%2Fen.wikipedia.org%3ATrain&rft.au=Atchison%2C+Topeka+and+Santa+Fe+Railway&rft.aulast=Atchison%2C+Topeka+and+Santa+Fe+Railway&rft.btitle=Rules%3A+Operating+Department&rft.date=1948&rft.genre=book&rft.pages=7&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Abook"><span style="display:none;"> </span></span></span></li>

<li id="cite_note-3"><span><b>^ [Hydrogen trains](http://www.hydrogencarsnow.com/blog2/index.php/hydrogen-vehicles/i-hear-the-hydrogen-train-a-comin-its-rolling-round-the-bend/)</span></li>

<li id="cite_note-4"><span><b>^ [Vehicle Projects Inc. Fuel cell locomotive](http://www.bnsf.com/media/news/articles/2008/01/2008-01-09a.html)</span></li>

<li id="cite_note-5"><span><b>^</b></span> <span><span>Central Japan Railway (2006). <i>Central Japan Railway Data Book 2006</i>. p. 16.</span><span title="ctx_ver=Z39.88-2004&rfr_id=info%3Asid%2Fen.wikipedia.org%3ATrain&rft.au=Central+Japan+Railway&rft.aulast=Central+Japan+Railway&rft.btitle=Central+Japan+Railway+Data+Book+2006&rft.date=2006&rft.genre=book&rft.pages=16&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Abook"><span style="display:none;"> </span></span></span></li>

<li id="cite_note-6"><span><b>^ ["Overview Of the existing Mumbai Suburban Railway"](http://web.archive.org/web/20080620033027/http://www.mrvc.indianrail.gov.in/overview.htm). _Official webpage of Mumbai Railway Vikas Corporation_. Archived from [the original](http://www.mrvc.indianrail.gov.in/overview.htm) on 2008-06-20<span>. Retrieved 2008-12-11</span>.</span><span title="ctx_ver=Z39.88-2004&rfr_id=info%3Asid%2Fen.wikipedia.org%3ATrain&rft.atitle=Overview+Of+the+existing+Mumbai+Suburban+Railway&rft.genre=article&rft_id=http%3A%2F%2Fwww.mrvc.indianrail.gov.in%2Foverview.htm&rft.jtitle=Official+webpage+of+Mumbai+Railway+Vikas+Corporation&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Ajournal"><span style="display:none;"> </span></span></span></li>

</ol>

</div>

需要從上面文本中找出這裡所有的域名—— askoxford.com;bnsf.com;hydrogencarsnow.com;mrvc.indianrail.gov.in;web.archive.org

該怎麼做?

match=re.findall(r'http(s:|:)\/\/(www.|ww2.|)([0-9a-z.A-Z-]*\.\w{2,3})',string)

for elem in match:

print(elem)

---

(':', 'www.', 'askoxford.com')

(':', 'www.', 'hydrogencarsnow.com')

(':', 'www.', 'bnsf.com')

(':', '', 'web.archive.org')

(':', 'www.', 'mrvc.indianrail.gov.in')

(':', 'www.', 'mrvc.indianrail.gov.in')

這裡用到了or運算符,match返回元組,保留()裡的模式部分。

3.查找電子郵件地址:

下面的正則表達式用於在長文本中查找電子郵件地址。

match=re.findall(r'([\w0-9-._]+@[\w0-9-.]+[\w0-9]{2,3})',string)

這些都是高級示例,提供的信息已經足夠幫你理解這些示例了。

結論

雖然正則表達式看起來令人生畏,但它在數據操作、創建特性和尋找模式方面具有高度的靈活性。

留言 點讚 關注

我們一起分享AI學習與發展的乾貨

編譯組:殷睿宣、李林虹

相關連結:

https://towardsdatascience.com/the-ultimate-guide-to-using-the-python-regex-module-69aad9e9ba56

如需轉載,請後臺留言,遵守轉載規範

相關焦點

  • Python「正則表達式」詳解(上)
    大家好,今天我們一起學習以下Python中的「正則表達式」,說到正則表達式,大家可能比較陌生,不過我卻要告訴你,你每天都在使用正則表達式,不要不承認,就問你最常見的,瀏覽器每天用不?淘寶經常逛不?你在搜索框裡輸入幾個文字,按下回車,就出來大量結果,你想想這是怎麼辦到的,是正則表達式,可以好不誇張的講,沒有正則表達式,就沒有搜尋引擎。
  • python正則表達式使用方法說明
    曾光紅/文 (同步發布豆瓜網)一、導入re庫python使用正則表達式要導入re庫。import re在re庫中。正則表達式通常被用來檢索查找、替換那些符合某個模式(規則)的文本。二、使用正則表達式步驟1、尋找規律;2、使用正則符號表示規律;3、提取信息,如果每一個字符都能匹配,則匹配成功;一旦有匹配不成功的字符則匹配失敗。
  • 三十一、深入Python中的正則表達式
    「@Author: Runsen」正則表達式應用的場景也非常多。常見的比如:搜尋引擎的搜索、爬蟲結果的匹配、文本數據的提取等等都會用到,所以掌握甚至精通正則表達式是一個硬性技能,非常必要。Python中則提供了強大的正則表達式處理模塊,即 re 模塊, 為Python的內置模塊。下面,我帶大家來一個入門demo例子,代碼如下:import rereg_string = "hello9527python@wangcai.@!
  • 原創通俗易懂的Python的正則表達式,建議收藏
    正則表達式正則表達式是一個特殊的字符序列,由普通字符和元字符組成。元字符能幫助你方便的檢查一個字符串是否與某種模式匹配。正則表達式應用的場景也非常多。常見的比如:搜尋引擎的搜索、爬蟲結果的匹配、文本數據的提取等等都會用到,所以掌握甚至精通正則表達式是一個硬性技能,非常必要。
  • 學習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學習第135課——初步了解正則表達式以及正則表達式的用法
    【每天幾分鐘,從零入門python編程的世界!】從現在開始,我們學習正則表達式。正則表達式,又稱規則表達式。(英語:Regular Expression,在代碼中常簡寫為regex、regexp或RE),計算機科學的一個概念。
  • 有趣的Python和正則表達式
    嘗試一下破壞並修復代碼,將代碼拆分成儘可能多的獨立表達式,通過函數或類為代碼片段創建模塊,然後將其還原成儘可能少的代碼行。因為每個正則表達式只能匹配有限數量的字符串並且具有有限數量的條件分支,所以它定義了一個有限狀態機(FSM)。
  • 「正則表達式」 python中的使用
    正則表達式的介紹在實際開發過程中經常會有查找符合某些複雜規則的字符串的需要,比如:郵箱、圖片地址、手機號碼等,這時候想匹配或者查找符合某些規則的字符串就可以使用正則表達式了。2.正則表達式概念正則表達式就是記錄文本規則的代碼3. 正則表達式的樣子0\d{2}-\d{8} 這個就是一個正則表達式,表達的意思是匹配的是座機號碼4.
  • python面試題匯總第06期-正則表達式(內附7題及答案)
    1.python正則表達式中匹配(match)和查找(search)的區別答:正則表達式中match和search的方法比較相似相同點:都是在一個字符串s中尋找pat子字符串,如果能找到答:利用python正則表達式re模塊中的sub方法,將標籤替換為空字符串,代碼如下:運行結果:python小當家 python面試題匯總4.python中用正則表達式提取字符串中所有域名:
  • 程式設計師入門基礎:python正則表達式貪婪匹配和非貪婪匹配
    此文為python正則表達式的高階入門,正則基礎入門請參考程式設計師入門基礎:python的正則表達式。一、貪婪匹配和非貪婪匹配舉例說明概念:print('非貪婪匹配',re.search('el+?':貪婪模式:正則表達式一般趨向於最大字符長度的匹配,也就是所謂的貪婪匹配。
  • 再見,正則表達式
    從一段指定的字符串中,取得期望的數據,正常人都會想到正則表達式吧?寫過正則表達式的人都知道,正則表達式入門不難,寫起來也容易。但是正則表達式幾乎沒有可讀性可言,維護起來,真的會讓人抓狂,別以為這段正則是你寫的就可以駕馭它,過個一個月你可能就不認識它了。完全可以說,天下苦正則久矣。今天給你介紹一個好東西,可以讓你擺脫正則的噩夢,那就是 Python 中一個非常冷門的庫 -- parse。
  • Python正則表達式,從入門到實戰,精華都在這裡
    正則表達式的相關知識Python的中 re 模塊,主要是用來處理正則表達式一個利用 re 模塊通過正則表達式來進行網頁數據的爬取和存儲1.1 正則表達式及作用正則表達式的英文是 regular expression,通常簡寫為 regex、regexp 或者RE,
  • Python正則表達式急速入門
    正則表達式在程序開發中會經常用到,比如數據(格式)驗證、替換字符內容以及提取字符串內容等等情況都會用到,但是目前許多開發人員對於正則表達式只是處於了解或者是基本會用的階段。一旦遇到大批量使用正則表達式的情況(例如網絡爬蟲)可以說基本上就抓瞎了。這篇文章我將帶領大家利用 Python 來學習一下正則表達式。
  • Python學習第136課——把正則表達式匹配的字符串分組
    【每天幾分鐘,從零入門python編程的世界!】我們對上節的代碼稍作修改,把代表國家代碼的模式部分和代表11位手機號數字的模式部分用小括號括起來,這樣就相當於給通過正則表達式匹配模式找到的字符串進行了分組。
  • Python正則表達式:特殊符號和字符
    正表達式為高級的文本模式匹配,抽取,與/或文本形式的搜索和替換功能提供了基礎。簡而言之,正則表達式(簡稱regex)是由一些字符和特殊符號組成的字符串,它描述了模式的重複或者表達多個字符。python通過標準庫中的re模塊來支持正則表達式。
  • Python正則表達式的七個使用範例
    作為一個概念而言,正則表達式對於Python來說並不是獨有的。但是,Python中的正則表達式在實際使用過程中還是有一些細小的差別。本文引用地址:http://www.eepw.com.cn/article/201807/383660.htm本文是一系列關於Python正則表達式文章的其中一部分。
  • Python:正則表達式基本符號總結
    說明:如果需要匹配的字符是正則表達式中的特殊字符,那麼可以使用\進行轉義處理,例如想匹配小數點可以寫成\.就可以了,因為直接寫.會匹配任意字符;同理,想匹配圓括號必須寫成和。在python中,如果使用正則表達式的話,需要導入re模塊,re模塊是一個內置模塊,直接import就可以使用,下面是re模塊中的核心函數。
  • python之:正則表達式-re模塊
    ----模糊匹配說明:正則表達式-所有操作對象只是字符串,多個返回list。本身是一門小型高度專業的程式語言,內嵌在python中,並通過re模塊實現,用C編寫的引擎執行方法:re.match(pattern, string) 從字符串的起始位置匹配,返回一個匹配子串。
  • java正則表達式入坑指南
    在日常開發工作中,無論你使用的語言是java、python、shell、golang還是C#, 正則表達式是程式語言中幾乎繞不開的話題。有了它,可以幫你快速定位到符合條件的文本內容。今天小編帶大家一起來學習下正則表達式,相信通過這篇文章的介紹,能為以後的工作提供一個更清晰的思路。
  • Python學習第137課——正則表達式中實現可選規則
    【每天幾分鐘,從零入門python編程的世界!】正則表達式英文是Regular Expression,各種程式語言中都是把它簡寫成Regex,或者Regexp或者re。這節我們學習如何在正則表達式中實現可選規則。