什麼是regular expression
一般在程式語言的應用上,程式設計人員會稱它為正規表達式,我個人覺得稱呼它為規則比對式較能反映它的應用,因為在絕大部分的應用上,正規表達式通常被用來檢索、搜尋比對、以至於替換那些符合某個樣態或模式的文字內容,而資料樣態的描述就是依regular expression(以下用re來簡稱)的語法規定來建立的。不只是python,許多程式設計語言都支援利用正規表達式進行檢索或搜尋文章內容的必要操作。
基本上,運用re規定的字元組合成樣本資料的型態結構,就能讓您在尋找資料或處理資料時方便的多。
一句話簡單扼要地說明:
〝正規表達式是設計用來解決我們對於目標文件或資料中特定樣本格式資料的搜尋及取得〞。
再更詳細一點的舉例說明,當我們要找出一篇文章中是否存在「人工智慧」這樣固定的字眼與否時,很容易用各種程式語言標配的文字串搜尋功能即可完成任務,但如果我們要檢查一篇文章或一堆資料中是否有身分證字號存在時該怎麼辦呢?因為我們要找的不是「身分證字號」這幾個字,而是資料中存在的疑似可能的真正的身分證字號如a223456789或A22345678或u123456789等,碰到類似這種課題時,還非得使用re不可。作法上,我們利用規則比對式規定的特殊字元描述並堆積出一種資料的樣態,再透過規則比對式提供的成員函式(方法)幫我們去比對標的文章或資料中是否有符合這種樣態的資料。
regular expression可以幫我們什麼忙
舉凡要從資料中找出電子郵件的資料、身分證資料、蒐集特定格式的資料、或是要控制用戶輸入的密碼符合複雜密碼原則(完整的密碼須符合包含文字、數字大小寫、及幾個字元等)或者用戶留存的電郵格式是否正確等,只要是對於資料符合特定樣式的收集及輸入資料符合規範的樣態等,這時候re就可以派上用場。尤其是我們未來在進行資料探勘、大數據分析或式進行爬蟲做資料收集時,在程式及資料運用領域時,它是我們必備的一項工具。另外一個特色是,regular expression是跨越各種程式語言的一項工具,無論您操作或設計上式用何種程式語言,大部分的程式語言,都支援re在程式內容中對於資料搜尋的操作。
在python中怎麼啟用regular expression
先介紹一個在python中最常用的regular expression的語法
import re
re.search(pattern, string)
import re:
在python中要使用re時,不需要做額外的安裝(如 pip install的指令,因為在python的程式中已經包含re的服務),但不可避免的,若我們設計這支程式時,若要運用re的功能時,就必須要程式的一開始新導入re模組。所以,
import re 就變成不可或缺。
re.search(pattern,string):
search是re模組中一個最常用的成員函式(方法),換句話說,在python中運用到regular expression時,您常會看到re.search這個指令。
在re.search指令後,小括符內包含的第一個參數pattern就是我們用regular expression規定的字元定義出來的資料樣本,而string就是我們要搜尋的標的文件。
re.search及re.findall是我們在regular expression最常用到的re成員函式(方法),兩者之間的差異在於search只能挑出符合比對樣態的第一項,但findall能將比對標的中全部符合樣態的資料以列表(list)的方式來容納。
舉例來說:
import re
re.search(`hi`, `abcdefghij1234kl5678mnopqrstuvwxyz`)
其中hi就是我們要尋找的字串,而後面的abcdefghij1234…..就是我們搜尋的文件。
這時候,讀者一定會說,上面這個例子,不是用python的find就可以做到,幹嘛還需要一個regular expression,沒錯,單看這個例子,確實有很多的函式可以完成任務,這樣的舉例,說明了re也可作為文字字串搜尋之用。但是,若我們的目的是要搜尋文件中是否存在數字呢?又或是找出兩段數字中間的內容?這時候,我相信就算是聰明如你的人也必須費盡心思解析文件才得以研判找出。
import re
re.search(`\d+`, `abcdefghij1234kl5678mnopqrstuvwxyz`)
以上的程式示範中,簡單的文字字串由hi變成奇怪的符號字串\d+,這樣就可以找出文件中是否存在數字達文西密碼, re很簡單的幫我們完成任務,而我們找出數字的pattern就是運用\d+來組成的,是不是很神奇呢?以下,我們就來了解re各個符號代表的意思,一些符號組成的pattern可以幫我們完成很多不可能的任務呢?
regular expression提供那些字元符號讓我們來構建找尋的資料樣本-pattern
re提供數十個特定字元來讓我們方便定義樣本資料,我們在這先介紹比較常見而且實用的特定字元,未來有機會,也許能介紹更多,甚至於您有更特殊的需要,相信運用google大師,您可以涉獵更多的特殊用法。
眾多特殊字元中,我將之分別歸類為:
定值特殊字元
. 代表這個字元可以是除了跳行\n之外的所有字元,所以當我們運用...定義代表三個隨意字元。
以下例子說明.的應用能讓我們能比對出符合`f..r`樣態的字串。
[] 如[abc],代表[]這一個字元只能是a或b或c,請注意,[]結果只能描述一個字元,所以常常會看到有人用[a-zA-Z0-9]來定義這個結果字元為除了符號外的英文字元或數字,而[]中也可以運用-符號來代表區間,若你要搜尋一個大樂透的區間號碼可以定義為[0-4][0-9],就代表結果這個數字的區間介於00~49之間。
以下例子說明[]的應用能讓我們能比對出符合[]中定義樣態的資料。
在上例中,[]內的定義為此字元必須為0~9的數字之一,而且我們也強調[]中描述為單一個字元,以至於對於後面的內容中我們比對出2,1,1的三個符合樣態資料。
[^] 如[^abc]於[]中最前頭加入^這個符號就代表這一個字元不是a也不是b也不是c,有點排除於外的概念,我們用下面的例子看看效果是什麼。
只要是非0~9的字元,包含句中的`,`號都被視為非0~9的樣態資料。
| 代表選擇項目,舉例若我們定義一個m(a|e)n,則代表搜尋的文件中存在man或men則會被挑出,若是wom(a|e)n,您應該可以理解要搜尋的是什麼。
以下例子說明 | 的應用能讓我們能比對出符合選擇項中定義樣態的資料。
\ \後面跟隨的英文字母(又分大小寫),這裡暫時介紹最常用的幾個字母,其實這幾個字母代表的意思跟我們前面介紹的幾個特定字元有類似或相同的用途。
\d 等同前面所列的[0-9]數字
\D 等同前面所列的[^0-9]非數字
\w 等同前面所列的[a-zA-Z_0-9] 數字或是英文字,包含底線_
\W 等同前面所列的[^a-zA-Z_0-9] 非數字且是非英文字
我們這邊舉一個例子示意給同學看
在上面這個例子的用途上,\d的功能跟前面提到的[0-9]一樣,同樣的,[^0-9]就跟\D的用途一樣。
定位點特殊字元
^ 代表搜尋的標的要以^後序的內容當開頭才算符合。
﹩ 代表搜尋的標的要以﹩前述的內容當結尾才算符合。
我們舉個簡單的例子說明定位點字元的用途。
數量特殊字元
- 若前置字元無括符號涵蓋,則代表前置的文字,應該要出現0次或多次。
+ 若前置字元無括符號涵蓋,則代表前置的文字,應該要出現至少1次或多次。
? 代表前置的文字應該要出現0次或1次。
{n} 括符內的數字定義前置文數字出現幾次或n次,也可用{n,m}來表示符合的資料應包含前置字元出現n-m次。
我們以下舉一些例子來說明上述數量字元搭配來用能達到的目的。
以下的例子說明怎麼例用特殊字元來定義樣本資料達到搜尋資料中疑似電話的內容呢?
下面的例子運用\d及{數量}的搭配來達到搜尋10位數的行動電話號碼來完成任務
但問題來了,搜尋的資料中也包含市話的電話號碼,市話的規則不同於行動電話規則,我們先來試試看怎麼理出市話的規則,下面的例字看來都能達到發現市話的目的,只是一例是結合[0-9]及數量字元?的組合,另一例則用\d及數量字元+的組合來完成,這樣的結果代表要達到同樣的目的,樣本資料樣態資料的定義不一定只有一種標準定義方法,您可多加運用練習,也許條條道路通羅馬,當然,越嚴謹的定義方法可以達到的準確性就越高。
當然,如果要兩種型態的電話資料都被搜尋出來,運用'|`將兩種樣態結合起來,也是這個例子很好的運用。
除了上述的舉例外,聰明的您也可練習看看可有一種組合就可以將市話及行動電話一網打盡呢?一訂有更佳的樣態資料定義方法的。
再接下來,我們綜合運用以上的特殊字元用來組合成一個資料樣本,用來篩出本文開始時期望的,從一段資料中找出疑似身分證字號的內容(請注意,是疑似)。
我們運用上面所學到的特殊字元堆疊並定義出在搜尋的文章或資料中包含的疑似身分證字號的內容(當然,部分的同學會發現這些身分證字號也許不符合身分證字號的檢核規定,果然是精明的學生,恭喜您能明察秋毫,但更嚴謹的檢核不包含在我們這次re的示意,請您原諒!)
透過regular expression找尋之後如何輸出
通常我們運用re.search搜尋後,會呈現兩種結果
- 當目標文件沒有我們要搜尋的樣本資料類型時,re會回應一個none的結果。
- 當搜尋後有找到符合樣本資料時,re會回應一個搜尋結果的物件,如下
執行後re回應的結果是一個re物件
這樣的回應內容在運用上比較不容易,接下來,介紹一些re物件的成員函式(方法)或物件的屬性,讓我們在應用這些取得的結果上更好運用。
執行後的結果
由以上的指令我們可以得到
re物件.string屬性 取得標的文件的內容
re物件.span()成員函式 取得符合樣本文件取得的區間
re 物件.group()成員函式 取得符合樣本的資料
關於regular expression還有很多的的樣本規格制訂字元及成員函式可運用,若在您還沒運用上之前,花很多的時間深入內容當然是一個好學的學生,但務實地來說,以上介紹的內容其實已經夠滿足您應用的大半,況且,學習後若沒時時練習,總容易就忘記。
建議您,在未來應用到re時,若有困難的議題時,可借助google大師,世界上不缺這方面的高手,若有時間,我會再針對re的議題再整理一些資料供大家參考。
留言列表