溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式

發(fā)布時(shí)間:2020-06-30 14:57:50 來源:億速云 閱讀:321 作者:清晨 欄目:編程語言

小編給大家分享一下用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討方法吧!

痛點(diǎn)

很多人的日常工作,都是要和大量的文本打交道的。

例如學(xué)者需要閱讀大量的文獻(xiàn)材料,從中找到靈感、數(shù)據(jù)與論據(jù)。

學(xué)生需要閱讀很多教科書和論文,然后寫自己的報(bào)告或者做幻燈。

財(cái)經(jīng)分析師,需要從大量的新聞報(bào)道中,找到行業(yè)的發(fā)展趨勢和目標(biāo)企業(yè)動(dòng)態(tài)的蛛絲馬跡。

不是所有的文本處理,都那么新鮮而有趣。

有一項(xiàng)重要但繁瑣的工作,就是從大量的文本當(dāng)中抽取結(jié)構(gòu)化的信息。

許多數(shù)據(jù)分析的場景,都要求輸入結(jié)構(gòu)化的信息。

例如在咱們之前介紹過的《貸還是不貸:如何用 Python 和機(jī)器學(xué)習(xí)幫你決策?》和《如何用 Python 和深度神經(jīng)網(wǎng)絡(luò)鎖定即將流失的客戶?》中,你都看到了,機(jī)器模型更喜歡被結(jié)構(gòu)化的表格信息來喂養(yǎng)。

用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式

然而,結(jié)構(gòu)化的信息,不一定就在那里,靜候你來使用。很多時(shí)候,它蘊(yùn)藏在以往生成的非結(jié)構(gòu)化文本中。

用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式

你可能早已習(xí)慣,人工閱讀文本信息,把關(guān)鍵點(diǎn)摘取出來,然后把它們拷貝粘貼放到一個(gè)表格中。從原理上講,這樣做無可厚非。但是實(shí)際操作里面,效率太低,而且太麻煩。

大部分人,是不愿意從事這種簡單重復(fù)的枯燥工作的。

一遍遍機(jī)械重復(fù)鼠標(biāo)劃定文本范圍,“Ctrl+C”、切換到表格文檔、找準(zhǔn)輸入位置,再 “Ctrl+V”……

這種事兒做得太多,對(duì)你的肩肘關(guān)節(jié),甚至是身心健康,都有可能造成不利影響。

想不想嘗試用一種更簡單的自動(dòng)化方式,替你快速完成這些煩人的操作步驟呢??

讀過本文后,希望你能找到答案。

樣例

這里,我們舉一個(gè)極端簡化的中文文本抽取信息例子。

之所以這樣做,是為了避免你在解讀數(shù)據(jù)上花費(fèi)太多時(shí)間。

我更希望,你能夠聚焦于方法,從而掌握新知。

假設(shè)一個(gè)高中班主任,高考后讓班長統(tǒng)計(jì)一下學(xué)生們的畢業(yè)去向。班長很認(rèn)真地進(jìn)行了調(diào)查,然后做了如下匯報(bào):

張華考上了北京大學(xué)
李萍進(jìn)了中等技術(shù)學(xué)校
韓梅梅進(jìn)了百貨公司
……

為了讓你對(duì)樣例足夠熟悉,甚至有共鳴,這里我從 1998 年版的新華字典中,“借鑒” 了部分內(nèi)容。

夠貼心吧?

現(xiàn)實(shí)生活中,一個(gè)班大概不會(huì)只有 3 個(gè)人,因此你可以想象這是一個(gè)長長的句子列表。

但其實(shí)班主任有個(gè)隱含的意思沒有表達(dá)出來,即:

我想要一張表格!

所以,看到這一長串的句子,你可以想象他的表情。

班長估計(jì)也很難堪:

想要表格你早說啊!

這時(shí)候,假設(shè)你是班長,怎么辦?

信息都在文本里面。但如果需要轉(zhuǎn)換成表格,就得一個(gè)個(gè)信息點(diǎn)去尋找和處理。

其實(shí),對(duì)于四五十人的班級(jí)來說,手動(dòng)操作也不是什么太難的事情。

但是設(shè)想一下,如果你需要處理的數(shù)據(jù)量,是這個(gè)例子的十倍、百倍甚至千萬倍呢?

繼續(xù)堅(jiān)持手動(dòng)處理?

這不僅麻煩,而且不現(xiàn)實(shí)。

我們需要找到一種簡單的方法,幫助我們自動(dòng)抽取相應(yīng)的信息。

此處我們使用的方法,是正則表達(dá)式。

正則

“正則表達(dá)式” 這個(gè)名字,初聽起來好像很玄妙。實(shí)際上,它是從英文 “regular expression” 翻譯過來的。

如果譯成白話,那就是 “有規(guī)律的表述形式”。

這,聽起來,是不是就更加接地氣了?

但是,給你補(bǔ)一下 “假行家 101” 課程:

說別人聽得懂的話,你能唬得住誰?

約定俗成,咱們繼續(xù)沿用 “正則表達(dá)式”,來稱呼它好了。

從創(chuàng)生之日起,它就給文本處理帶來了高效率。

但是,用它的主要人群,卻不是時(shí)常跟文字打交道的作家、編輯、學(xué)者、文員,而是……

程序員!

程序員寫的代碼,是文本;程序員處理的數(shù)據(jù),很多也是文本格式。其中便有很多顯著的規(guī)律可循。

正是靠著正則表達(dá)式這種獨(dú)門秘籍,許多別人做起來,需要昏天黑地一整周的任務(wù),程序員可以半小時(shí)搞定,然后喝著咖啡等下班。

即便到了泛人工智能的今天,正則表達(dá)式依然有許多令你意想不到的應(yīng)用。

例如人機(jī)對(duì)話系統(tǒng)。

你可能看了新聞報(bào)道,總以為人機(jī)對(duì)話都是靠著知識(shí)圖譜或者深度學(xué)習(xí)搞出來的。

不能說這里面,沒有上述炫酷技術(shù)的參與。但它們充其量,只占其中一部分,或許還只是一小部分。

生產(chǎn)實(shí)踐里面,大量的對(duì)話規(guī)則后面,并不是讓你倍感神奇深?yuàn)W的神經(jīng)網(wǎng)絡(luò),而是一堆正則表達(dá)式。

你可能會(huì)擔(dān)心,這樣高端的應(yīng)用技術(shù),自己能掌握嗎?

答案是:

當(dāng)然!

正則表達(dá)式,并不難學(xué)。

尤其是當(dāng)你把它和 Python 結(jié)合到一起,那簡直就是效率神器了。

我們這就來看看,正則表達(dá)式怎么幫我們識(shí)別出樣例文本里面 “人名” 和 “去向” 信息。

試練

請(qǐng)你開啟一個(gè)瀏覽器,鍵入這個(gè)網(wǎng)址(https://regex101.com/)。

你會(huì)看見如下界面。

用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式

它可是一個(gè)正則表達(dá)式實(shí)驗(yàn)的利器。我教 INFO 5731 課程時(shí),學(xué)生們就是在掌握了這個(gè)工具以后,迅速玩兒轉(zhuǎn)了正則表達(dá)式。

這么好的工具,一定要價(jià)不菲吧?

不,它是免費(fèi)的。你放心大膽使用就好了。

我們首先把左側(cè)的編程語言,從默認(rèn)的 PHP ,調(diào)整為 Python。

之后,把需要進(jìn)行處理的文本,貼到中間空白的大文本框里面。

用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式

下面我們來嘗試進(jìn)行 “匹配”。

什么叫做匹配呢?

就是你寫一個(gè)表達(dá)式,電腦便拿著雞毛當(dāng)令箭,在每一行文本上,都認(rèn)認(rèn)真真地找有沒有符合該表達(dá)式的文本段落。

如有,則會(huì)高亮顯示出來。

這里我們觀察一下,發(fā)現(xiàn)每個(gè)句子里面,人員去向前面,都有一個(gè) “了” 字。

好,我們就在中部上方小文本框里,把 “了” 字輸入進(jìn)去。

用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式

可以看到,三句話里面的 “了”,全都亮了

這就是你接觸到的第一種匹配方式 —— 按照字符原本的意思來查找一致的內(nèi)容。

因?yàn)闃永谋镜囊?guī)律性,我們可以把 “了” 當(dāng)成一個(gè)定位符,它后面,到句子結(jié)束位置,是 “去向” 信息。

咱們需要找的一半結(jié)構(gòu)化信息,不就是這個(gè) “去向” 嗎?

我們嘗試匹配 “去向”。

怎么匹配呢?這次每一行的字兒都不一樣?。?/p>

沒關(guān)系,正則表達(dá)式強(qiáng)大之處,此時(shí)就顯示出來了。

你可以用一個(gè)點(diǎn)號(hào),也就是.,表示任意字符。

字母、數(shù)字、標(biāo)點(diǎn)…… 甚至是中文,也能涵蓋在內(nèi)。

然后我們繼續(xù)想想看,去向信息這里,會(huì)有幾個(gè)字呢?

不好說。

例子里面這簡單的三句話,就有 “4 個(gè)字” 或者 “6 個(gè)字” 兩種情況。

所以,我們無法指定去向信息里面字符的長度。

但這也沒關(guān)系,我們只需要用一個(gè)星號(hào)(*),就可以代表出現(xiàn)次數(shù),從 0 到無窮大都可以匹配。

當(dāng)然,實(shí)際情況中,是不會(huì)真出現(xiàn)無窮大的。

我們在剛才輸入的基礎(chǔ)上,加上.*,結(jié)果就成了這個(gè)樣子:

用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式

不錯(cuò)嘛!

不過似乎去向信息和 “了” 字兒都是一樣顏色的高亮。那不就混到了一起嗎?

我們可不想這樣。

怎么辦?

請(qǐng)你在.* 的兩側(cè),嘗試加入一對(duì)小括號(hào)(注意,不要用中文全角符號(hào))試試看。

用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式

你會(huì)發(fā)現(xiàn),這次 “了” 依然用藍(lán)色表示,而后面的去向信息,已經(jīng)變成了綠色。

這一對(duì)小括號(hào),很重要,它叫做 “分組”,是提取信息的基本單位。

我們的任務(wù)已經(jīng)解決了一半了,是吧?

下面我們來嘗試把人名一并抽取出來。

我們來找人名的錨定位置。

細(xì)細(xì)觀察,你不難發(fā)現(xiàn),每個(gè)人名的后面,都有個(gè)動(dòng)詞跟著。

升學(xué)的同學(xué),用的是 “考” 字,而就業(yè)的同學(xué),用的是 “進(jìn)” 字。

我們先嘗試一下 “考” 字。

這里我們嘗試直接把 “考” 字放在 “了” 字以前。但是你會(huì)發(fā)現(xiàn),什么匹配結(jié)果也沒有。

用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式

為什么?

回看數(shù)據(jù),你會(huì)發(fā)現(xiàn),人家用的原詞是 “考上了”。

當(dāng)然這里我們可以輸入 “上” 字。不過你要考慮一下更為通用的情況。

好比說,“考取了” 怎么辦?“考入了” 呢?

更好的方式,是繼續(xù)使用我們剛才學(xué)會(huì)的 “大招”,在 “考” 和 “了” 之間,插入一個(gè).*。

這時(shí)候,你的正則表達(dá)式的樣子是 考.*了(.*)

看,第一行的信息成功匹配了吧?

但是,那后面還有兩行沒有匹配,怎么辦?

我們依樣畫葫蘆,就會(huì)發(fā)現(xiàn),使用進(jìn).*了(.*) 就能正確匹配后兩行。

用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式

問題來了:

匹配第一行的,匹配不了后兩行,反之亦然。

這不好。我們希望寫的表達(dá)式,能夠更通用。

怎么辦?

我們看看正則表達(dá)式當(dāng)中 “或” 關(guān)系的表示。

這里,我們可以把兩個(gè)字符用豎線隔開,旁邊用中括號(hào)括起來,代表兩者任一出現(xiàn),都算匹配成功。

也就是,把正則表達(dá)式,寫成這樣:[考|進(jìn)].*了(.*)

用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式

太棒了,三行的內(nèi)容都已經(jīng)匹配成功。

這里,動(dòng)詞詞組,和代表時(shí)態(tài)的 “了” 作為中間錨定信息,我們可以放心大膽,把之前的人名信息,提取出來了。

也就是這樣寫:(.*)[考|進(jìn)].*了(.*)

用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式

注意此時(shí),人名分組是綠色,去向分組是紅色的。

我們成功提取了兩組信息!慶祝一下!

可是,如果你給班主任看這里的結(jié)果,估計(jì)他不會(huì)滿意。

表格,我要表格!

別著急,該 Python 出場了。

下面我們嘗試在 Python 把數(shù)據(jù)正式提取出來。

環(huán)境

本文的配套源代碼,我放在了 Github 上。

你可以在我的公眾號(hào) “玉樹芝蘭”(nkwangshuyi)后臺(tái)回復(fù) “regex”,查看完整的代碼鏈接。

用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式

如果你對(duì)我的教程滿意,歡迎在頁面右上方的 Star 上點(diǎn)擊一下,幫我加一顆星。謝謝!

注意這個(gè)頁面的中央,有個(gè)按鈕,寫著 “在 Colab 打開”(Open in Colab)。請(qǐng)你點(diǎn)擊它。

然后,Google Colab 就會(huì)自動(dòng)開啟。

用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式

我建議你點(diǎn)一下上圖中紅色圈出的 “COPY TO DRIVE” 按鈕。這樣就可以先把它在你自己的 Google Drive 中存好,以便使用和回顧。

用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式

Colab 為你提供了全套的運(yùn)行環(huán)境。你只需要依次執(zhí)行代碼,就可以復(fù)現(xiàn)本教程的運(yùn)行結(jié)果了。

如果你對(duì) Google Colab 不熟悉,沒關(guān)系。我這里有一篇教程,專門講解 Google Colab 的特點(diǎn)與使用方式。

為了你能夠更為深入地學(xué)習(xí)與了解代碼,我建議你在 Google Colab 中開啟一個(gè)全新的 Notebook ,并且根據(jù)下文,依次輸入代碼并運(yùn)行。在此過程中,充分理解代碼的含義。

這種看似笨拙的方式,其實(shí)是學(xué)習(xí)的有效路徑。

代碼

首先,讀入 Python 正則表達(dá)式包。

import re

然后,我們把數(shù)據(jù)準(zhǔn)備好。注意為了演示代碼的通用性,我這里在最后加了一行文字,區(qū)別于之前的文字規(guī)律,看看我們的代碼能否正確處理它。

data = """張華考上了北京大學(xué)
李萍進(jìn)了中等技術(shù)學(xué)校
韓梅梅進(jìn)了百貨公司
他們都有光明的前途"""

然后,該寫正則表達(dá)式了。你真的需要自己手動(dòng)來寫嗎?

當(dāng)然不必。

強(qiáng)大的 regex101 網(wǎng)站,已經(jīng)幫助我們準(zhǔn)備好了。

用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式

請(qǐng)你點(diǎn)擊上圖中紅色圈出的按鈕,網(wǎng)站會(huì)為你準(zhǔn)備好一個(gè)初始代碼的模板,可以匹配你需要的模式。

用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式

你不需要完全照搬代碼。其中有這樣一句,是很重要的,拷貝過來,貼到 Colab Notebook 就好。

regex = r"(.*)[考|進(jìn)].*了(.*)"

以上就是你的正則表達(dá)式,在 Python 里面應(yīng)有的樣子。

我們準(zhǔn)備一個(gè)空列表,用來接收數(shù)據(jù)。

mylist = []

接著,寫一個(gè)循環(huán)。

for line in data.split('\n'):
 mysearch = re.search(regex, line)
 if mysearch:
   name = mysearch.group(1)
   dest = mysearch.group(2)
   mylist.append((name, dest))

我給你解釋一下這個(gè)循環(huán)里面,各條語句的含義:

data.split('\n') 把文本數(shù)據(jù)按行來拆分開。這樣我們就可以針對(duì)每一行,來獲取數(shù)據(jù)。mysearch = re.search(regex, line) 這一句嘗試匹配模式到該行內(nèi)容。if mysearch 這個(gè)判斷語句,是讓程序分辨一下,該行是否有我們要找的模式。例如最后一行文字,里面并沒有咱們前面分析的文字模式。遇到這樣的行,直接跳過。name = mysearch.group(1) 是說匹配的第一組內(nèi)容,也就是 regex101 網(wǎng)站里綠色代表的人名分組存到 name 變量里。下一句依次類推。注意 group 對(duì)應(yīng)你正則表達(dá)式里面小括號(hào)出現(xiàn)的順序,從 1 開始計(jì)數(shù)。mylist.append((name, dest)) 把該行抽取到的信息,存入到咱們之前定義的空列表里面。

注意,如果不加 mysearch = re.search(regex, line) 這一句,程序會(huì)對(duì)每一行都嘗試匹配并且抽取分組內(nèi)容,那么結(jié)果就會(huì)報(bào)這樣的錯(cuò)誤:

用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式

所以你看,用正則表達(dá)式抽取信息時(shí),不能蠻干。

此時(shí),我們查看一下 mylist 這個(gè)列表里面的內(nèi)容:

mylist

結(jié)果為:

[('張華', '北京大學(xué)'), ('李萍', '中等技術(shù)學(xué)校'), ('韓梅梅', '百貨公司')]

不錯(cuò),一個(gè)不多,一個(gè)不少,恰好是我們需要的。

我們要把它導(dǎo)出成為表格。方法有很多,但是最簡便順手的,是用 Pandas 數(shù)據(jù)分析軟件包。

import pandas as pd

只需要利用 pd.DataFrame 函數(shù),我們就能把上面列表和元組(tuple)組成的一個(gè)二維結(jié)構(gòu),變成數(shù)據(jù)框。

df = pd.DataFrame(mylist)
df.columns = ['姓名', '去向']

注意,這里我們還非常細(xì)心地修改了表頭。

看看你的勞動(dòng)成果吧:

df

用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式

有了數(shù)據(jù)框,轉(zhuǎn)換成為 Excel ,就是一行代碼的事情了:

df.to_excel("dest.xlsx", index=False)

進(jìn)入 Files 標(biāo)簽頁,刷新并且查看一下當(dāng)前目錄下的內(nèi)容:

用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式

這個(gè) dest.xlsx 就是輸出的結(jié)果了。下載之后我們可以用 Excel 打開查看。

用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式

任務(wù)完成!

看完了這篇文章,相信你對(duì)用Python和正則表達(dá)式抽取文本結(jié)構(gòu)化信息的方式有了一定的了解,想了解更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI