旗下產(chǎn)業(yè): A產(chǎn)業(yè)/?A實(shí)習(xí)/?A計(jì)劃
全國(guó)統(tǒng)一咨詢熱線:010-5367 2995
首頁(yè) > 熱門文章 > 大數(shù)據(jù)分析 > 大數(shù)據(jù)分析Python的正則表達(dá)式Regular Expressions使用方法

大數(shù)據(jù)分析Python的正則表達(dá)式Regular Expressions使用方法

時(shí)間:2020-05-23來源:5wd995.cn點(diǎn)擊量:作者:Sissi
時(shí)間:2020-05-23點(diǎn)擊量:作者:Sissi



  全力以赴地進(jìn)入數(shù)據(jù)集是從事數(shù)據(jù)科學(xué)工作的任何人的使命之一。通常,這意味著要進(jìn)行數(shù)字運(yùn)算,但是當(dāng)我們的數(shù)據(jù)集主要基于文本時(shí),我們?cè)撛趺崔k?我們可以使用正則表達(dá)式。在本教程中,我們將仔細(xì)研究如何在Python中使用正則表達(dá)式(regex)。
 

  正則表達(dá)式(regex)本質(zhì)上是文本模式,可用于自動(dòng)搜索和替換文本字符串中的元素。這可以使清理和使用基于文本的數(shù)據(jù)集變得更加容易,從而省去了手動(dòng)搜索大量文本的麻煩。
 

  正則表達(dá)式可以在多種編程語(yǔ)言中使用,并且已經(jīng)存在很長(zhǎng)時(shí)間了!
 

  不過,在本教程中,我們將學(xué)習(xí)Python中的正則表達(dá)式,因此需要基本熟悉關(guān)鍵的Python概念,例如if-else語(yǔ)句,while和for循環(huán)等。在本教程結(jié)束時(shí),您將熟悉Python regex的工作原理,并能夠使用Python regex模塊中的基本模式和功能re來分析文本字符串。您還將獲得有關(guān)正則表達(dá)式如何與熊貓配合使用以處理大型文本語(yǔ)料庫(kù)的介紹。

AAA教育
 

  讓我們深入研究有關(guān)每個(gè)人最不喜歡的電子郵件類型的一些數(shù)據(jù):垃圾郵件和欺詐。
 

  我們的任務(wù):分析垃圾郵件
 

  在本教程中,我們將使用Kaggle的欺詐電子郵件語(yǔ)料庫(kù)。它包含1998年至2007年之間發(fā)送的數(shù)千種網(wǎng)絡(luò)釣魚電子郵件。它們非常有趣,易于閱讀。
 

  您可以在這里找到完整的語(yǔ)料庫(kù)。但是,我們將從使用一些電子郵件學(xué)習(xí)基本的正則表達(dá)式命令開始。如果需要,您也可以使用我們的測(cè)試文件,也可以在完整的語(yǔ)料庫(kù)中嘗試使用。
 

  介紹Python的Regex模塊

大數(shù)據(jù)分析Python
 

  首先,我們將通過打開測(cè)試文件,將其設(shè)置為只讀并讀取來準(zhǔn)備數(shù)據(jù)集。我們還將其分配給變量fh(用于“文件句柄”)。
 

  請(qǐng)注意,我們?cè)谀夸浡窂街凹觬。此技術(shù)將字符串轉(zhuǎn)換為原始字符串,這有助于避免某些機(jī)器讀取字符的方式引起的沖突,例如Windows上目錄路徑中的反斜杠。
 

  現(xiàn)在,假設(shè)我們要找出電子郵件的來源。我們可以自己嘗試使用原始Python:

大數(shù)據(jù)分析Python
 

  但這并沒有給我們確切的需求。如果您看一下我們的測(cè)試文件,我們可以找出原因并修復(fù)它,但是,讓我們使用Python的re模塊并使用正則表達(dá)式來做吧!
 

  我們將從導(dǎo)入Python的re模塊開始。然后,我們將使用一個(gè)名為的函數(shù)re.findall(),該函數(shù)返回在正在查看的字符串中定義的模式的所有實(shí)例的列表。
 

  外觀如下:

大數(shù)據(jù)分析Python
 

  這與原始Python的長(zhǎng)度基本相同,但這是因?yàn)檫@是一個(gè)非常簡(jiǎn)單的示例。您嘗試做的越多,Python正則表達(dá)式就可以為您節(jié)省更多的精力。
 

  在繼續(xù)之前,讓我們仔細(xì)看看re.findall()。此函數(shù)采用形式為的兩個(gè)參數(shù)re.findall(pattern, string)。在這里,pattern代表我們要查找的子字符串,并string代表我們要在其中查找的主字符串。主字符串可以包含多行。在這種情況下,我們讓它fh使用選定的電子郵件來搜索所有文件。
 

  該.*是一個(gè)字符串模式的簡(jiǎn)寫。正則表達(dá)式通過使用這些速記模式來查找文本中的特定模式而起作用,因此讓我們看一下其他一些常見示例:
 

  常見的Python正則表達(dá)式模式
 

  我們r(jià)e.findall()上面使用的模式包含一個(gè)完整拼寫的字符串"From:"。當(dāng)我們確切地知道我們要查找的內(nèi)容(精確到實(shí)際字母以及它們是否為大寫或小寫)時(shí),這很有用。如果我們不知道我們想要的字符串的確切格式,我們將會(huì)迷路。幸運(yùn)的是,正則表達(dá)式具有解決此情況的基本模式。讓我們看看在本教程中使用的那些:
 

  1)w匹配字母數(shù)字字符,表示az,AZ和0-9。它還與下劃線_和破折號(hào)-相匹配。

  2)d 匹配數(shù)字,表示0-9。

  3)s 匹配空白字符,包括制表符,換行符,回車符和空格字符。

  4)S 匹配非空格字符。

  5).匹配除換行符外的任何字符n。
 

  掌握了這些正則表達(dá)式模式后,您將在繼續(xù)進(jìn)行解釋的同時(shí)快速理解上面的代碼。
 

使用正則表達(dá)式模式
 

  現(xiàn)在,我們可以.*在re.findall("From:.*", text)上面的行中解釋的用法。讓我們.先來看:

大數(shù)據(jù)分析Python
 

  通過在.旁邊添加一個(gè)From:,我們可以在其旁邊查找另一個(gè)字符。因?yàn)?查找除以外的任何字符n,所以它捕獲了我們看不到的空格字符。我們可以嘗試更多的點(diǎn)來驗(yàn)證這一點(diǎn)。

大數(shù)據(jù)分析Python
 

  看起來加點(diǎn)確實(shí)為我們獲得了線的其余部分。但是,這很繁瑣,而且我們不知道要添加多少點(diǎn)。這是星號(hào)符號(hào)*出現(xiàn)的位置。
 

  *匹配模式左側(cè)的零個(gè)或多個(gè)實(shí)例。這意味著它將尋找重復(fù)模式。當(dāng)我們尋找重復(fù)的模式時(shí),我們說搜索是“貪婪的”。如果我們不尋找重復(fù)的模式,則可以將搜索稱為“非貪婪”或“懶惰”。
 

  讓我們構(gòu)建一個(gè)貪婪的搜索.用*。

大數(shù)據(jù)分析Python
 

  因?yàn)?匹配在其左側(cè)指示的模式的零個(gè)或多個(gè)實(shí)例,并且.位于此處的左側(cè),所以我們能夠獲取From:字段中的所有字符,直到行尾。這將用精美簡(jiǎn)潔的代碼打印出整行。
 

  我們甚至可以更進(jìn)一步,僅隔離名稱。讓我們使用它re.findall()來返回包含模式的行列表,"From:.*"就像之前一樣。match為了整潔,我們將其分配給變量。接下來,我們將遍歷列表。在每個(gè)循環(huán)中,我們將re.findall再次執(zhí)行,匹配第一個(gè)引號(hào)以僅選擇名稱:

大數(shù)據(jù)分析Python
 

  注意,我們?cè)诘谝粋€(gè)引號(hào)旁邊使用了反斜杠。反斜杠是一個(gè)特殊字符,用于轉(zhuǎn)義其他特殊字符。例如,當(dāng)我們想將引號(hào)用作字符串文字而不是特殊字符時(shí),可以使用反斜杠將其轉(zhuǎn)義,例如:\"。如果我們不使用反斜杠轉(zhuǎn)義上面的模式,它將變?yōu)?quot;".*"",Python解釋器將其讀取為兩個(gè)空字符串之間的句點(diǎn)和星號(hào)。它將產(chǎn)生錯(cuò)誤并破壞腳本。因此,至關(guān)重要的是我們?cè)谶@里用反斜杠將引號(hào)引起來。
 

  匹配第一個(gè)引號(hào)后,.*獲取行中的所有字符,直到下一個(gè)引號(hào)也被轉(zhuǎn)義為模式。這使我們得到的名稱只是帶引號(hào)的名稱。該名稱也打印在方括號(hào)中,因?yàn)閞e.findall返回的匹配項(xiàng)在列表中。
 

  如果我們想要電子郵件地址怎么辦?

大數(shù)據(jù)分析Python
 

  看起來很簡(jiǎn)單,不是嗎?僅模式不同。讓我們來看一看。
 

  這是我們僅匹配電子郵件地址的前部分的方式:

大數(shù)據(jù)分析Python
 

  電子郵件總是包含一個(gè)@符號(hào),因此我們從它開始。電子郵件中@符號(hào)前的部分可能包含字母數(shù)字字符,這w是必需的。但是,由于某些電子郵件包含句點(diǎn)或破折號(hào),所以這還不夠。我們添加S以查找非空白字符。但是,w\S只會(huì)得到兩個(gè)字符。添加*以查找重復(fù)。因此,模式的前部如下所示:\w\S*@。
 

  現(xiàn)在查看@符號(hào)后面的模式:

大數(shù)據(jù)分析Python
 

  域名通常包含字母數(shù)字字符,句點(diǎn)和短劃線,因此a .可以。為了使它更貪婪,我們使用擴(kuò)展了搜索范圍*。這使我們可以匹配任何字符,直到行尾。
 

  如果我們仔細(xì)觀察這條線,會(huì)發(fā)現(xiàn)每封電子郵件都封裝在尖括號(hào)<和>中。我們的模式.*包括右括號(hào)>。讓我們對(duì)其進(jìn)行補(bǔ)救:

大數(shù)據(jù)分析Python
 

  電子郵件地址以字母數(shù)字字符結(jié)尾,因此我們將模式設(shè)置為w。因此,在@符號(hào)后面有.*\w,這表示我們想要的模式是一組以字母數(shù)字字符結(jié)尾的任何類型的字符。不包括>。
 

  因此,我們的完整電子郵件地址格式如下所示:\w\S*@.*\w。
 

  !這需要花費(fèi)很多時(shí)間。接下來,我們將介紹一些通用re功能,這些功能在開始重新組織語(yǔ)料庫(kù)時(shí)將非常有用。
 

  常用的Python正則表達(dá)式函數(shù)
 

  re.findall()無疑是有用的,但它不是我們可以使用的唯一內(nèi)置函數(shù)re:
 

  1)re.search()

  2)re.split()

  3)re.sub()
 

  在使用它們?yōu)槲覀兊臄?shù)據(jù)集添加一些順序之前,讓我們一一看一下。
 

  研究()
 

  While re.findall()匹配字符串中某個(gè)模式的所有實(shí)例并在列表中返回它們,re.search()匹配字符串中一個(gè)模式的第一個(gè)實(shí)例,并將其作為re匹配對(duì)象返回。

大數(shù)據(jù)分析Python
 

  像一樣re.findall(),re.search()也有兩個(gè)參數(shù)。第一個(gè)是要匹配的模式,第二個(gè)是要在其中找到模式的字符串。在這里,我們將結(jié)果分配給match變量以保持整潔。
 

  由于re.search()返回re匹配對(duì)象,因此無法通過直接打印來顯示名稱和電子郵件地址。相反,我們必須首先對(duì)該group()函數(shù)應(yīng)用該函數(shù)。我們已經(jīng)在上面的代碼中打印了這兩種類型。如我們所見,group()將match對(duì)象轉(zhuǎn)換為字符串。

  我們還可以看到,打印match顯示的屬性超出字符串本身,而打印match.group()僅顯示字符串。
 

  re.split()
 

  假設(shè)我們需要一種快速的方法來獲取電子郵件地址的域名。我們可以通過三個(gè)正則表達(dá)式操作來做到這一點(diǎn),如下所示:

大數(shù)據(jù)分析Python
 

  第一行很熟悉。我們返回一個(gè)字符串列表,每個(gè)字符串包含F(xiàn)rom:字段的內(nèi)容,并將其分配給變量。接下來,我們遍歷列表以查找電子郵件地址。同時(shí),我們循環(huán)訪問電子郵件地址,并使用該re模塊的split()功能將每個(gè)地址切成兩半,用@符號(hào)作為分隔符。最后,我們打印它。
 

  re.sub()
 

  另一個(gè)方便的re功能是re.sub()。就像函數(shù)名稱所暗示的那樣,它替換字符串的一部分。一個(gè)例子:

大數(shù)據(jù)分析Python
 

  我們之前已經(jīng)在第一行和第二行看到了任務(wù)。在第三行,我們r(jià)e.sub()在上應(yīng)用address,這是From:電子郵件標(biāo)題中的完整字段。
 

  re.sub()需要三個(gè)參數(shù)。第一個(gè)是要替換的子字符串,第二個(gè)是我們要替換的字符串,第三個(gè)是主字符串本身。
 

  正則表達(dá)式與pandas
 

  現(xiàn)在,我們掌握了Python正則表達(dá)式的基礎(chǔ)知識(shí)。但是通常對(duì)于數(shù)據(jù)任務(wù),我們實(shí)際上并沒有使用原始的Python,而是使用了pandas庫(kù)?,F(xiàn)在,將我們的正則表達(dá)式技能帶入熊貓工作流程,將其提升到一個(gè)新的水平。
 

  如果您以前從未使用過熊貓,請(qǐng)不要擔(dān)心。我們將逐步遍歷代碼,以免您迷路。但是,如果您想更詳細(xì)地了解熊貓,請(qǐng)查看我們的熊貓教程或我們提供的有關(guān)numpy和熊貓的完全交互式課程。
 

  使用Python Regex和Pandas對(duì)電子郵件進(jìn)行排序
 

  我們的語(yǔ)料庫(kù)是一個(gè)包含數(shù)千封電子郵件的單個(gè)文本文件(不過,同樣,在本教程中,我們使用的是一個(gè)只有兩個(gè)電子郵件的較小文件,因?yàn)樵谡麄€(gè)語(yǔ)料庫(kù)上打印正則表達(dá)式工作的結(jié)果會(huì)使這篇文章過長(zhǎng))。
 

  我們將使用正則表達(dá)式和熊貓將每封電子郵件的各個(gè)部分分類為適當(dāng)?shù)念悇e,以便可以更輕松地閱讀或分析語(yǔ)料庫(kù)。
 

  我們將每封電子郵件分為以下類別:
 

  1)sender_name

  2)sender_address

  3)recipient_address

  4)recipient_name

  5)date_sent

  6)subject

  7)email_body
 

  這些類別中的每一個(gè)都將成為我們的熊貓數(shù)據(jù)框(即我們的表格)中的一列。這將使我們更輕松地分別處理和分析每個(gè)列。
 

  我們將繼續(xù)處理我們的小樣本,但是值得重申的是,正則表達(dá)式使我們可以編寫更簡(jiǎn)潔的代碼。簡(jiǎn)潔的代碼減少了我們的機(jī)器必須執(zhí)行的操作數(shù)量,從而加快了我們的分析過程。使用我們的兩封電子郵件的小文件,并沒有太大的區(qū)別,但是,如果您嘗試使用和不使用正則表達(dá)式來處理整個(gè)語(yǔ)料庫(kù),您將開始看到其優(yōu)勢(shì)!
 

  準(zhǔn)備腳本
 

  首先,讓我們導(dǎo)入所需的庫(kù),然后再次打開文件。
 

  除了re和之外pandas,我們email還將導(dǎo)入Python的軟件包,這將有助于電子郵件的正文。僅使用正則表達(dá)式時(shí),電子郵件的主體相當(dāng)復(fù)雜。它甚至可能需要足夠的清理才能保證有自己的教程。因此,我們將使用完善的email軟件包來節(jié)省一些時(shí)間,讓我們專注于學(xué)習(xí)正則表達(dá)式。


 

  我們還創(chuàng)建了一個(gè)空列表emails,用于存儲(chǔ)字典。每本詞典將包含每封電子郵件的詳細(xì)信息。
 

  現(xiàn)在,讓我們開始應(yīng)用正則表達(dá)式!

Python
 

  注意:為簡(jiǎn)潔起見,我們剪裁了上面的打印輸出。如果您在自己的機(jī)器上打印此文件,它將顯示其中包含的所有內(nèi)容,contents而不是...像上面那樣結(jié)束。
 

  我們使用re模塊的split函數(shù)將整個(gè)文本塊分割fh為單獨(dú)的電子郵件列表,然后將其分配給變量contents。這很重要,因?yàn)槲覀兿Mㄟ^使用for循環(huán)遍歷列表來逐一處理電子郵件。但是,我們?nèi)绾沃腊醋址指?quot;From r"?
 

  我們之所以知道這一點(diǎn),是因?yàn)樵诰帉懩_本之前我們已經(jīng)查看了文件。我們不必細(xì)讀其中的數(shù)千封電子郵件。只是前幾個(gè),看看數(shù)據(jù)的結(jié)構(gòu)是什么樣子。只要有可能,最好在開始使用代碼之前先關(guān)注實(shí)際數(shù)據(jù),因?yàn)槟?jīng)常會(huì)發(fā)現(xiàn)諸如此類的有用功能。
 

  我們已經(jīng)截取了原始文本文件的屏幕截圖:

Python
 

  電子郵件以“ From r”開頭
 

  綠色方框是第一封電子郵件。藍(lán)色方框是第二封電子郵件。如我們所見,這兩封電子郵件均以開頭"From r",并以紅色框突出顯示。
 

  我們?cè)诒窘坛讨惺褂闷墼p電子郵件語(yǔ)料庫(kù)的原因之一是,當(dāng)數(shù)據(jù)雜亂無章,不熟悉且沒有文檔時(shí),我們不能僅僅依靠代碼來整理數(shù)據(jù)。這將需要一雙人眼。正如我們剛剛顯示的,我們必須研究語(yǔ)料庫(kù)本身以研究其結(jié)構(gòu)。
 

  像這樣雜亂無章的數(shù)據(jù)可能需要大量清理。例如,即使我們使用本教程將要構(gòu)建的完整腳本來計(jì)算此集合中的3977封電子郵件,但實(shí)際上還有更多。某些電子郵件實(shí)際上并不以開頭"From r",因此不會(huì)單獨(dú)計(jì)算。(不過,為了簡(jiǎn)潔起見,我們將繼續(xù)處理該問題,并用分隔所有電子郵件"From r"。)
 

  還要注意,我們contents.pop(0)用來擺脫列表中的第一個(gè)元素。這是因?yàn)?quot;From r"字符串在第一封電子郵件之前。拆分該字符串后,它將在索引0處生成一個(gè)空字符串。我們將要編寫的腳本是為電子郵件設(shè)計(jì)的。如果我們嘗試在空字符串上使用它,則可能會(huì)引發(fā)錯(cuò)誤。擺脫空字符串可以使我們避免破壞腳本。
 

  使用For循環(huán)獲取每個(gè)名稱和地址
 

  接下來,我們將使用contents列表中的電子郵件。

Python
 

  在上面的代碼中,我們使用for循環(huán)來遍歷,contents因此我們可以依次處理每封電子郵件。我們創(chuàng)建了一個(gè)詞典,emails_dict其中包含每封電子郵件的所有詳細(xì)信息,例如發(fā)件人的地址和姓名。實(shí)際上,這些是我們發(fā)現(xiàn)的第一批物品。
 

  這是一個(gè)三步過程。首先從尋找From:領(lǐng)域開始。

Python
 

  在第1步中,我們From:使用re.search()函數(shù)查找整個(gè)字段。該.裝置除了任何字符n,并且*其延伸到行的結(jié)尾。然后,我們將其分配給變量sender。
 

  但是,數(shù)據(jù)并不總是那么簡(jiǎn)單。它可能包含驚喜。例如,如果沒有From:字段怎么辦?該腳本將引發(fā)錯(cuò)誤并中斷。我們?cè)诓襟E2中避免了這種情況下的錯(cuò)誤。

Python
 

  為了避免由于缺少From:字段而導(dǎo)致的錯(cuò)誤,我們使用一條if語(yǔ)句來檢查sendernot None。如果是,我們分配s_email和s_name的值,None以便腳本可以繼續(xù)運(yùn)行而不是意外中斷。
 

  如果您在自己的文件中使用本教程,則可能已經(jīng)意識(shí)到使用正則表達(dá)式會(huì)變得混亂。例如,這些if-else語(yǔ)句是在編寫主體時(shí)對(duì)主體使用反復(fù)試驗(yàn)的結(jié)果。編寫代碼是一個(gè)反復(fù)的過程。值得注意的是,即使本教程看起來很簡(jiǎn)單,實(shí)際實(shí)踐也需要進(jìn)行更多的實(shí)驗(yàn)。
 

  在第2步中,我們使用之前的regex模式\w\S*@.*\w,該模式與電子郵件地址匹配。
 

  我們將對(duì)名稱使用其他策略。每個(gè)名稱都由左側(cè):子字符串的冒號(hào)()"From:"和<右側(cè)電子郵件地址的左尖括號(hào)()界定。因此,我們使用它:.*<來查找名稱。我們擺脫:并<從每個(gè)結(jié)果的時(shí)刻。
 

  現(xiàn)在,讓我們打印出代碼的結(jié)果以查看它們的外觀。

Python
 

  同樣,我們有匹配對(duì)象。每次我們將re.search()字符串應(yīng)用于字符串時(shí),都會(huì)生成匹配對(duì)象。我們必須將它們變成字符串對(duì)象。
 

  我們這樣做之前,記得,如果沒有From:現(xiàn)場(chǎng),sender將具有的價(jià)值None,因此也將s_email和s_name。因此,我們必須再次檢查這種情況,以便腳本不會(huì)意外中斷。讓我們看看如何首先構(gòu)建代碼s_email。

Python
 

  在步驟3A中,我們使用一條if語(yǔ)句檢查s_emailnot None,否則它將引發(fā)錯(cuò)誤并破壞腳本。
 

  然后,我們只需將s_emailmatch對(duì)象轉(zhuǎn)換為字符串并將其分配給sender_email變量。我們將其添加到emails_dict字典中,這將使我們?nèi)蘸髮⒓?xì)節(jié)轉(zhuǎn)換為pandas數(shù)據(jù)框變得異常容易。
 

  我們s_name在步驟3B中所做的幾乎完全相同。

Python
 

  正如我們以前那樣,我們首先檢查s_name是不是None在步驟3B。
 

  然后,在將字符串分配給變量之前,我們兩次使用re模塊的re.sub()函數(shù)。首先,我們刪除冒號(hào)和它與名稱之間的所有空白字符。我們:s*用一個(gè)空字符串代替""。然后,我們刪除空格字符和名稱另一邊的尖括號(hào),再次用空字符串替換它。最后,在將字符串分配給之后sender_name,我們將其添加到字典中。
 

  讓我們檢查一下結(jié)果。

Python
 

  完善。我們已經(jīng)隔離了電子郵件地址和發(fā)件人的姓名。我們還將它們添加到字典中,該字典將很快投入使用。
 

  現(xiàn)在我們已經(jīng)找到了發(fā)件人的電子郵件地址和名稱,我們將執(zhí)行完全相同的步驟來獲取字典的收件人的電子郵件地址和名稱。
 

  首先,我們找到To:領(lǐng)域。

Python
 

  接下來,我們搶先在場(chǎng)景recipient是None。

Python
 

  如果recipient不是None,則用于re.search()查找包含電子郵件地址和收件人姓名的匹配對(duì)象。否則,我們傳遞r_email和r_name的值None。
 

  然后,將匹配對(duì)象轉(zhuǎn)換為字符串并將其添加到字典中。

Python
 

  由于From:和To:字段的結(jié)構(gòu)相同,因此我們可以對(duì)兩者使用相同的代碼。我們需要為其他字段定制略有不同的代碼。
 

  獲取電子郵件的日期
 

  現(xiàn)在確定發(fā)送電子郵件的日期。

Python
 

  我們Date:為From:和To:字段獲取具有相同代碼的字段。
 

  并且,就像我們對(duì)這兩個(gè)字段所做的一樣,我們檢查Date:分配給date_field變量的字段是否不是None。

Python
 

  我們已經(jīng)打印了出來,date_field.group()以便我們可以更清楚地看到字符串的結(jié)構(gòu)。它包括日期,DD MMM YYYY格式的日期和時(shí)間。我們只想要日期。日期的代碼與姓名和電子郵件地址基本相同,但更為簡(jiǎn)單。也許唯一令人困惑的是正則表達(dá)式模式\d+\s\w+\s\d+。
 

  日期以數(shù)字開頭。因此,我們用d它來解釋它。但是,作為日期的DD部分,它可以是一位或兩位數(shù)字。在這里+變得重要。在Python正則表達(dá)式中,+匹配其左側(cè)1個(gè)或多個(gè)模式實(shí)例。d+因此,無論日期是DD還是一兩位數(shù)字,它都將與日期的DD部分匹配。
 

  在那之后,有一個(gè)空間。這是由占的s,它查找空白字符。因此,該月由三個(gè)字母組成w+。然后它撞到另一個(gè)空間s。年份由數(shù)字組成,因此我們d+再次使用。
 

  完整模式\d+\s\w+\s\d+起作用的原因是它是一個(gè)精確的模式,在兩側(cè)均以空格字符為界。
 

  接下來,我們None像以前一樣檢查值。

Python
 

  如果date不是None,則將其從匹配對(duì)象轉(zhuǎn)換為字符串,并將其分配給變量date_sent。然后,將其插入字典中。
 

  在繼續(xù)之前,我們應(yīng)該注意一個(gè)關(guān)鍵點(diǎn)。+并且*看起來相似,但它們可以產(chǎn)生非常不同的結(jié)果。讓我們以日期字符串為例。

Python
 

  如果使用*,則將匹配零個(gè)或多個(gè)匹配項(xiàng)。+匹配一個(gè)或多個(gè)事件。我們已經(jīng)打印了兩種情況的結(jié)果。有很大的不同。如您所見,+獲取完整日期,而*獲取空格和數(shù)字31。
 

  接下來,是電子郵件的主題行。
 

  獲取電子郵件主題
 

  和以前一樣,我們使用相同的代碼和代碼結(jié)構(gòu)來獲取所需的信息。

Python
 

  現(xiàn)在我們對(duì)Python正則表達(dá)式的使用越來越熟悉了,不是嗎?它與以前的代碼大致相同,不同之處在于,我們"Subject: "用空字符串代替僅獲取主題本身。
 

  獲取電子郵件的正文
 

  要插入字典的最后一項(xiàng)是電子郵件的正文。

Python
 

  將標(biāo)頭與電子郵件正文分開是一項(xiàng)非常復(fù)雜的任務(wù),尤其是當(dāng)許多標(biāo)頭以一種或另一種方式不同時(shí)。在原始的無組織數(shù)據(jù)中很少發(fā)現(xiàn)一致性。對(duì)我們來說幸運(yùn)的是,這項(xiàng)工作已經(jīng)完成。Python的email軟件包非常擅長(zhǎng)此任務(wù)。
 

  請(qǐng)記住,我們已經(jīng)較早導(dǎo)入了該軟件包?,F(xiàn)在,我們將其message_from_string()功能應(yīng)用于item,以將完整的電子郵件轉(zhuǎn)換為emailMessage對(duì)象。Message對(duì)象由標(biāo)頭和有效負(fù)載組成,它們分別對(duì)應(yīng)于電子郵件的標(biāo)頭和正文。
 

  接下來,我們將其get_payload()功能應(yīng)用于Message對(duì)象。此功能隔離電子郵件的正文。我們將其分配給變量body,然后將其插入到emails_dict鍵下的字典中"email_body"。
 

  為什么使用電子郵件軟件包而不是正文
 

  您可能會(huì)問,為什么使用emailPython軟件包而不是regex?這是因?yàn)槟壳斑€沒有很好的方法來處理Python正則表達(dá)式,而這不需要大量的清理工作。這意味著可能需要另外一份教程。
 

  值得檢查一下我們?nèi)绾巫龀鲞@樣的決定。但是,我們需要先了解[ ]正則表達(dá)式中的方括號(hào),然后才能這樣做。
 

  [ ]匹配放置在其中的任何字符。例如,如果我們要查找"a","b"或"c"字符串,則可以將其[abc]用作模式。我們上面討論的模式也適用。[\w\s]會(huì)找到字母數(shù)字或空格字符。例外是.,它成為方括號(hào)內(nèi)的文字周期。
 

  現(xiàn)在,我們可以更好地了解我們是如何決定使用電子郵件軟件包的。
 

  窺視數(shù)據(jù)集可發(fā)現(xiàn)電子郵件標(biāo)題在字符串"Status: 0"或處停止"Status: R0",并"From r"在下一封電子郵件的字符串前結(jié)束。因此,我們可以Status:\s*\w*\n*[\s\S]*From\sr*用來僅獲取電子郵件正文。[\s\S]*適用于大塊的文本,數(shù)字和標(biāo)點(diǎn)符號(hào),因?yàn)樗梢运阉骺瞻谆蚍强瞻鬃址?br />  

  不幸的是,有些電子郵件包含多個(gè)"Status:"字符串,而另一些則不包含"From r",這意味著我們會(huì)將電子郵件拆分成多于或少于電子郵件列表中詞典的數(shù)量。它們與我們已經(jīng)擁有的其他類別不匹配。使用熊貓時(shí),這會(huì)產(chǎn)生問題。因此,我們決定利用該email軟件包。
 

  創(chuàng)建詞典列表
 

  最后,將字典追加emails_dict到emails列表中:

Python
 

  我們可能要emails在此時(shí)打印列表以查看其外觀。如果您只是一直在使用我們的小樣本文件,那么這將是反高潮的,但是在整個(gè)語(yǔ)料庫(kù)中,您將看到正則表達(dá)式的強(qiáng)大功能!
 

  我們還可以print(len(emails_dict))查看列表中有多少個(gè)詞典,因此還有電子郵件。如前所述,整個(gè)語(yǔ)料庫(kù)包含3977。
 

  這是完整的代碼:

Python
Python
Python
 

  如果使用我們的示例文本文件運(yùn)行它,將會(huì)得到以下結(jié)果:

Python
 

  我們已經(jīng)打印出emails列表中的第一項(xiàng),它顯然是帶有鍵和值對(duì)的字典。因?yàn)槲覀兪褂昧薴or循環(huán),所以每個(gè)字典都具有相同的鍵但值不同。
 

  我們已替換為item,"email content here"以便我們不會(huì)打印出電子郵件的全部?jī)?nèi)容并阻塞屏幕。如果您要使用實(shí)際數(shù)據(jù)集在家打印此文件,則會(huì)看到整個(gè)電子郵件。
 

用熊貓?zhí)幚頂?shù)據(jù)
 

  有了列表中的詞典,我們使熊貓圖書館的工作變得無比輕松。每個(gè)鍵將成為列標(biāo)題,每個(gè)值將成為該列中的一行。
 

  我們要做的就是應(yīng)用以下代碼:

Python
 

  通過這一行,我們emails使用pandas DataFrame()函數(shù)將字典列表轉(zhuǎn)換為數(shù)據(jù)框。我們也將其分配給變量。
 

  而已。現(xiàn)在,我們有了一個(gè)復(fù)雜的熊貓數(shù)據(jù)框。這實(shí)際上是一個(gè)整潔的表格,其中包含我們從電子郵件中提取的所有信息。
 

  讓我們看一下前幾行。

Python
 

  該dataframe.head()函數(shù)僅顯示前幾行,而不顯示整個(gè)數(shù)據(jù)集。這需要一個(gè)論點(diǎn)。一個(gè)可選參數(shù)允許我們指定要顯示多少行。在這里,n=3讓我們查看三行。
 

  我們還可以精確地找到我們想要的東西。例如,我們可以找到從特定域名發(fā)送的所有電子郵件。但是,讓我們學(xué)習(xí)一種新的正則表達(dá)式模式,以提高找到所需項(xiàng)目的精度。
 

  管道符號(hào)會(huì)|在其任一側(cè)尋找字符。例如,a|b尋找a或b。
 

  |可能看起來與相同[ ],但是它們確實(shí)有所不同。假設(shè)我們要匹配要么"crab","lobster"或"isopod"。使用crab|lobster|isopod會(huì)比有意義[crablobsterisopod],不是嗎?前者將尋找每個(gè)單詞,而后者將尋找每個(gè)字母。
 

  現(xiàn)在,我們|來查找從一個(gè)或另一個(gè)域名發(fā)送的所有電子郵件。

Python
 

  我們?cè)谶@里使用了相當(dāng)長(zhǎng)的代碼。讓我們從內(nèi)而外開始。
 

  emails_df['sender_email']選擇標(biāo)記為的列sender_email。接下來,str.contains(epatra|spinfinder)返回True是否在該列中找到子字符串"epatra"或"spinfinder"。最后,外部emails_df[]返回行的視圖,其中該sender_email列包含目標(biāo)子字符串。好漂亮!
 

  我們也可以查看來自各個(gè)單元的電子郵件。為此,我們經(jīng)歷了四個(gè)步驟。在步驟1中,我們找到"sender_email"列包含字符串的行的索引"@spinfinder"。注意我們?nèi)绾问褂谜齽t表達(dá)式來執(zhí)行此操作。

Python
 

  在步驟2中,我們使用索引查找電子郵件地址,該loc[]方法作為具有多個(gè)不同屬性的Series對(duì)象返回該電子郵件地址。我們?cè)谙旅鎸⑵浯蛴〕鰜硪圆榭雌渫庥^。

Python
 

  在第3步中,我們從系列對(duì)象中提取電子郵件地址,就像從列表中提取項(xiàng)目一樣。您可以看到它的類型現(xiàn)在是class。

Python
 

  步驟4是提取電子郵件正文的位置。

Python
 

  在步驟4中,emails_df['sender_email'] == "bensul2004nng@spinfinder.com"找到該sender_email列包含value 的行"bensul2004nng@spinfinder.com"。接下來,['email_body'].values查找email_body同一行中的列的值。最后,我們打印出該值。
 

  如您所見,我們可以通過多種方式使用正則表達(dá)式,它也可以與大熊貓一起使用!如果您的正則表達(dá)式工作包含大量的反復(fù)試驗(yàn),請(qǐng)不要?dú)?,尤其是在您剛剛?cè)腴T時(shí)!
 

  其他資源
 

  自從幾年前正則表達(dá)式從生物學(xué)躍升為工程學(xué)以來,正則表達(dá)式已取得了巨大的發(fā)展。如今,正則表達(dá)式已在不同的編程語(yǔ)言中使用,其中除了其基本模式之外還有一些變體。我們已經(jīng)學(xué)習(xí)了很多Python正則表達(dá)式,并且如果您想將它提高到一個(gè)新的水平,那么我們的Python數(shù)據(jù)清理高級(jí)課程可能是一個(gè)不錯(cuò)的選擇。
 

  您還可以在官方參考資料中找到一些幫助,例如Python 有關(guān)其模塊的文檔re。Google有更快的參考資料。
 

  如果您愿意,也可以開始探索Python regex與其他形式的regex Stack Overflow帖子之間的區(qū)別。

  如果您需要數(shù)據(jù)集進(jìn)行試驗(yàn),則Kaggle和StatsModels很有用。
 

  最后,這是我們制作的Regex速查表,它也非常有用。




 

預(yù)約申請(qǐng)免費(fèi)試聽課

填寫下面表單即可預(yù)約申請(qǐng)免費(fèi)試聽!怕錢不夠?可先就業(yè)掙錢后再付學(xué)費(fèi)! 怕學(xué)不會(huì)?助教全程陪讀,隨時(shí)解惑!擔(dān)心就業(yè)?一地學(xué)習(xí),可推薦就業(yè)!

?2007-2021/北京漫動(dòng)者教育科技有限公司版權(quán)所有
備案號(hào):京ICP備12034770號(hào)

?2007-2022/ 5wd995.cn 北京漫動(dòng)者數(shù)字科技有限公司 備案號(hào): 京ICP備12034770號(hào) 監(jiān)督電話:010-53672995 郵箱:bjaaa@aaaedu.cc

京公網(wǎng)安備 11010802035704號(hào)

網(wǎng)站地圖