Python for Informatics 第11章之正則表達(dá)式(四)
注:以下文章原文來(lái)自于Dr Charles Severance 的 《Python for Informatics》
11.3 組合查詢和抽取
如果我們想以“X-”字符串開頭的行中找到數(shù)字,就像下面兩行字符串:
X-DSPAM-Confidence: 0.8475
X-DSPAM-Probability: 0.0000
但我們不只是要任意行中的任意浮點(diǎn)數(shù),而是具備上面格式的行中的數(shù)字。
我們可以創(chuàng)建以下正則表達(dá)式來(lái)選擇這樣的行:
^X-.*: [0-9.]+
這個(gè)表達(dá)式的含義是以“X-”兩個(gè)字符開頭,后面跟了任意個(gè)字符“.*",接著是一個(gè)冒號(hào)":"和空格" ",在空格之后呢是一個(gè)及以上的數(shù)字或小數(shù)點(diǎn)“[0-9.]+”。大家要注意的是方括號(hào)中的"[.]"不是匹配任何字符,而是匹配真正的".",這與方括號(hào)外的"."要予以區(qū)分。
這是一個(gè)非常緊湊的表達(dá)式,它將非常匹配我們感興趣的行:
import re hand = open('mobx-short.txt') for line in hand: line = line.rstrip() if re.search('^X-.*: [0-9.]+', line) print(line)
當(dāng)我們運(yùn)行這個(gè)程序,我們可以看到我們想要的數(shù)據(jù)被完美的過(guò)濾顯示。
X-DSPAM-Confidence: 0.8475
X-DSPAM-Probability: 0.0000
X-DSPAM-Confidence: 0.6178
X-DSPAM-Probability: 0.0000
但是我們必須使用split解決提取數(shù)字的問(wèn)題。然而當(dāng)這個(gè)問(wèn)題簡(jiǎn)單到能用split解決時(shí),我們可以使用正則表達(dá)式的另一特點(diǎn),一步達(dá)到查找和解析功能。
圓括號(hào)()是正則表達(dá)式中的另一特殊字符。當(dāng)我們添加圓括號(hào)至表達(dá)式中,在字符串的匹配過(guò)程中它們將被忽略,但是當(dāng)你使用findall()時(shí),圓括號(hào)表示你想整個(gè)正則表達(dá)式被匹配,但是你只抽取位于圓括號(hào)內(nèi)你感興趣的那部分字符串。
所以我們對(duì)程序修改如下:
import re hand = open('mbox-short.txt') for line in hand: line = line.rstrip() x = re.findall('^X-.*: ([0-9.]+)', line) if len(x) > 0 : print(x)
我們?cè)谡齽t表達(dá)式中對(duì)匹配浮點(diǎn)數(shù)字部分添加圓括號(hào),并且用findall()代替search(),返回我們想要的浮點(diǎn)數(shù)字部分。這個(gè)程序的輸出如下:
['0.8475']
['0.0000']
['0.6178']
['0.0000']
['0.6961']
['0.0000']
..
雖然這些在列表中的數(shù)字還需要從字符串轉(zhuǎn)換為浮點(diǎn)數(shù),但是我們應(yīng)用正則表達(dá)式的能力同時(shí)查找和抽取了我們感興趣的的信息。
下面是使用這個(gè)技巧的另一個(gè)案例。如果你查看文件,你會(huì)發(fā)現(xiàn)有許多行是這樣的格式:
Details: http://source.sakaiproject.org/viewsvn/?view=rev&rev=39772
如果我們想用同樣的技巧抽取所有修訂號(hào)(行末尾的整數(shù)),我們可以這樣編寫代碼:
import re hand = open('mbox-short.txt') for line in hand: line = line.rstrip() x = re.findall('^Details:.*rev=([0-9]+)', line) if len(x) > 0 : print(x)
我們的正則表達(dá)式的是這樣的,以"Details:"開頭,之后可以是任意字符”.*",然后是"rev=",最后是一個(gè)以上的數(shù)字。我們希望行是匹配整個(gè)正則表達(dá)式,但我們只需要圓括號(hào)中"[0-9]+"的數(shù)字。當(dāng)我們運(yùn)行程序時(shí),將得到以下輸出:
['39772']
['39771']
['39770']
['39769']
...
記住,"[0-9]+"是貪婪的,它將嘗試抽取任何可能的數(shù)字,所以我們得到的每個(gè)字符串都有五個(gè)數(shù)字。正則表達(dá)式庫(kù)在行的開頭和結(jié)尾兩個(gè)方向進(jìn)行擴(kuò)展,只到它數(shù)到一個(gè)非數(shù)字的字符。
我們可以用正則表達(dá)式重做本書先前的一個(gè)練習(xí)。在這個(gè)練習(xí)中我們對(duì)每個(gè)郵件的時(shí)間感興趣,我們尋找的行的格式如下:
From stephen.marquard@uct.ac.za Sat Jan 5 09:14:16 2008
并且我們想抽取每一行中日期中的小時(shí)信息。先前我們通過(guò)兩次調(diào)用split實(shí)現(xiàn)。第一次我們將行分離成單詞,然后我們對(duì)第五個(gè)單詞基于冒號(hào)再次分離,拉出我們感興趣的兩個(gè)字符。
假定要查找的行是良好格式化的,那么只要想到少的代碼就可以實(shí)現(xiàn)。但是當(dāng)你為確保程序中碰到不具備這樣格式而失效,而添加必要的錯(cuò)誤檢驗(yàn)(或者一個(gè)try/except塊)時(shí),這個(gè)代碼將會(huì)膨脹到10-15行,并且難以讀懂。
我們可以用下面的正則表達(dá)式使工作更簡(jiǎn)單:
^From .* [0-9][0-9]:
這個(gè)表達(dá)式的含義是以"From "開頭(注意空格),然后跟著任意個(gè)字符".*",接著又是一個(gè)空格,然后是兩個(gè)數(shù)字"[0-9][0-9]",再接著是一個(gè)冒號(hào)。我們要找的就是具備這樣格式的行。
為了在findall中只抽出表示小時(shí)的兩位數(shù)字,我們將表達(dá)式修改如下:
^From .* ([0-9][0-9]):
最后這個(gè)程序是這樣的:
import re hand = open('mbox-short.txt') for line in hand: line = line.rstrip() x = re.findall('ˆFrom .* ([0-9][0-9]):', line) if len(x) > 0 : print(x)
程序運(yùn)行結(jié)果如下:
['09']
['18']
['16']
['15']
...
相關(guān)閱讀:
Python for Informatics 第11章 正則表達(dá)式(一)
Python for Informatics 第11章之正則表達(dá)式(二)
關(guān)于Python for Informatics 第11章之正則表達(dá)式(四)就給大家介紹到這里,希望對(duì)大家有所幫助。后續(xù)還會(huì)持續(xù)更新,更多精彩內(nèi)容敬請(qǐng)關(guān)注!
相關(guān)文章
python GUI庫(kù)圖形界面開發(fā)之PyQt5窗口布局控件QStackedWidget詳細(xì)使用方法
這篇文章主要介紹了python GUI庫(kù)圖形界面開發(fā)之PyQt5窗口布局控件QStackedWidget詳細(xì)使用方法,需要的朋友可以參考下2020-02-02python中使用百度音樂(lè)搜索的api下載指定歌曲的lrc歌詞
這篇文章主要介紹了python中使用百度音樂(lè)搜索的api下載指定歌曲的lrc歌詞,同時(shí)也分析出了歌曲的下載地址,需要的朋友可以參考下2014-07-07使用Python對(duì)mongo數(shù)據(jù)庫(kù)中字符串型正負(fù)數(shù)值比較大小
這篇文章主要介紹了使用Python對(duì)mongo數(shù)據(jù)庫(kù)中字符串型正負(fù)數(shù)值比較大小,2023-04-04Python的matplotlib繪圖如何修改背景顏色的實(shí)現(xiàn)
這篇文章主要介紹了Python的matplotlib繪圖如何修改背景顏色的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07Python API len函數(shù)操作過(guò)程解析
這篇文章主要介紹了Python API len函數(shù)操作過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03Python讀取txt文件數(shù)據(jù)的方法(用于接口自動(dòng)化參數(shù)化數(shù)據(jù))
這篇文章主要介紹了Python讀取txt文件數(shù)據(jù)的方法(用于接口自動(dòng)化參數(shù)化數(shù)據(jù)),需要的朋友可以參考下2018-06-06快速解決cv2.imread()讀取圖像為BGR的問(wèn)題
這篇文章主要介紹了快速解決cv2.imread()讀取圖像為BGR的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-03-03