正規表示式

      在〈正規表示式〉中尚無留言

正規表示式

 re是 Regular Expression 的縮寫. 中文稱為正規表示式. 是一種用特定符號來表示字串內容要求的格式.
比如輸入一組電話號碼, “0987-就北七-就北七”, 顯然這不是電話號碼.
而 “0987-9879-87” 這組顯然是電話號碼, 但分隔文字 “-” 出現的位置怪怪的, 所以也不符合我們要求的格式.
我希望這字串裏所有的字都是數字, 然後前四碼要加 ‘-‘, 接下來每三碼就加 ‘-‘ “, 比如 “0987-987-987” 那就符合上面藍色字的要求.
藍色部份, 是用我們熟悉的語言表達出來. 電腦當然看不懂, 所以我們就要發明一種電腦可以看懂的表達方式, 這種方式就叫正規表示式. 

re模組

電腦可以看得懂的表達方式, 這句話好像很正常, 但仔細想一想, 電腦只看得懂 0 跟 1 啊. 所以就必需再撰寫一個函數, 用來解析這種表達方式. Python使用re模組來解析正規表示式. 所以嚴格來說, 正規表示式是用來讓 re模組看得懂的表達方式.

下面的pattern, 就是樣板、樣式的意思, 裏面的符號都是正規表示式. re.match(pattern, 字串) 會將字串進行核對, 是否符合pattern的要求. 若符合就會傳回一個Match物件, 否則就傳回None

import re
pattern="\d\d\d\d-\d\d\d-\d\d\d"
if re.match(pattern, '0987-987-987'):
    print("It's a phone number")
else:
    print("wrong number")

pattern裏那串很胎哥(骯髒)的符號, 到底是啥意思. 這就很讓人頭大了, 因為要背起來, 偏偏本人怎麼背也背不起來, 所以只好寫這篇文章方便日後查詢用.

跳脫, 轉譯字元

在Python字串中常看到 “\n” , 這種 “\”叫跳脫字元. 那如果想要純粹是 “\”的一般字元呢, 那就要使用 “\\”.

然而在正規表示式中, “\”又是另一種轉譯字元, 所以在pattern中若要表達 “\”, 就要使用  “\\\\”. 因此為了省麻煩, 就會在字串前加一個  “r”, 宣告不要把 “\”當成轉譯字元. 所以pattern就可以寫成 “\\”. 如下

import re
pattern1=r"\d\d\d\d\\\d\d\d\-\d\d\d" #只需二個 \\
pattern2="\d\d\d\d\\\\\d\d\d\-\d\d\d" #需四個 \\\\

單一字表示式

\d : 一個數字. 如’00\d’, ‘007’符合(match), ’00A’不符合
\w : 一個字母或數字. 如’00\w’, ‘007’及 ’00a’都符合
\s  : 一個空格或Tab
.     : 任何字元都符合, 包含了符號及空格

長度表示式

*  : 任意個字元
+  : 至少1個字元
?  : 0 或1 個字元
{n} : n 個字元
{n, m} : n-m個字元

\d{3}\s+\d{2,5} : 如 “123   45678 幾個空格都可以
\d{4}-\d{3}-\d{3} : “0987-987-987”

範圍表示式

[0-9a-zA-z\_]  : 一個數字或一個字母或底線
[0-9a-zA-z\_]+  : 至少(一個數字或一個字母或底線), 如 “a12-4567abc”
[a-zA-z\_][0-9]{9} : 開頭必需是字母, 後面9 個數字. 這就是台灣身份証的表示式

頭尾表示式

^  : 行開頭. ^\d, 開頭必需是數字
$  : 行結尾. \d$, 結尾必需是數字

re函數

re.match(pattern, ‘字串’) : 若有批配, 傳回Match物件, 否則傳回None
re.findall(pattern, ‘字串’) : 傳回3個數字連在一起的list

pattern1=r"\d{3}"
print(re.findall(pattern1, "abc12345678a"))
結果 : 
['123', '456']

re.split(pattern, ‘字串’) : 切割

pattern1=r"[\s\,]+"
print(re.split(pattern1, "abc   123,,456 78a"))
結果 : 
['abc', '123', '456', '78a']

分組

re.match()可以加入 “()” 進行分組, 使用m.group()取出. group(0)是原始字串

m = re.match(r'^(\d{4})-(\d{3,8})-(\d{3})', '0987-987-766')
print(m.group(0))
print(m.group(1))
print(m.group(2))
print(m.group(3))

compile

運算正規表示式時, 會先將pattern進行編譯, 然後才批配. 如果同一個表示式要批配1000個字串, 那就要編譯1000次, 再批配1000次, 電腦不煩我們看了也煩.

所以可以先編譯一次, 再利用編譯後的物件進行批配. 利用編譯後的物件批配時, 就不需再傳入pattern了.

pattern1=r"[\s\,]+"
rc=re.compile((pattern1))
r=rc.split("abc   123,,456 78a")
print(r)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *