Regular Expression 正規表達式是什麼?
就是用一套事先定義好的符號,來表達資料規則的方式。
Regular Expression 拿來幹嘛?
Search & Replace:可以用它的語法來搜尋或取代指定的字串,不需要傳統的方法做字串處理
Validate:可以拿來驗證某些格式,例如信箱、手機號碼等。
Reformat:可以把某種格式直接轉換成另一種格式
使用 Regular Expression 的好處
語法精簡:在不同的程式語言都可以使用一樣的表達式
速度非常快:效能比用原來的字串方法快
支援度佳:目前很多工具都可以支援正規表達式
規則
頭尾用 /
包住
/abc/
普通字元/abc/
/a/
apple
// a
特殊字元 [^$.|?*+(/
:
用到特殊符號前面要用反斜線來跳脫
/if \(true/
if (true) { doSomthing() }
// if true
任意字元/./
/a.man/
I'm a man
// a man
abman
// abman
**g
全域範圍**
這個 g 是 global 的意思,如果沒有加上 g,就只會 match 到第一個 match 到的字串:
/a/
a a a a a
// a
/a/g
a a a a a
// a a a a a
多個字元 /[aA]/
:
/[aA]/g
An apple
// A a
/[aeiuo]/g
There is an apple
// e e i a a e
多個字元的簡寫 /[a-z]/
選出區間之間的字,也可以像第二個例子這樣連用
/[a-z]/g
There is an apple
// here is an apple
/[a-zA-z]/g
Hello World 888
// Hello World
/[1-9]/g
09237487367
// 9237487367
選到不是什麼什麼的字元 ^
/[^H]/g
Hello World
// ello World
/[^0-9]/g
123 hahaha
// hahaha
多個字元的縮寫
\d
數字,就和 [0-9] 的意思相同
\w
英數字和底線,和 [A-Za-z0-9] 的意思相同
\s
空白
/\we/g
There is an apple
// here le
/\d\d/g
I have 10 dollar
// 10
\D
非數字,和 [^\d] 的意思相同
\W
非英數字和底線,和 [^\w] 的意思相同
\S
非空白,和 [^\s] 的意思相同
/\D/g
1 **+** 2 **=** 5 **?
// + = ?**
**\b
match 到 \w 的邊界**
邊界就是至少要有一邊為空的意思,例如 This is a book 這個範例,如果只想 match 到 is 的話,可以用 \b
包覆:
/\bis\b/
This is a book
// is
出現的次數
*
出現任意次數
+
至少出現一次
?
出現零或一次
/l*/g
Hello World
// ll ld
也可以 {} 用這種寫法來指定出現的次數,也可以設置最少和最多次數的範圍:
{次數}
{最少次數, 最多次數}
/l{2}/
He**ll**o Wolrd
// ll
// 只規定最少一次,一次以上都會被選到
/l{1}/g
He**ll**o Wor**l**d
// l l
出現頭尾與結尾
^
要出現在開頭
$
要出現在結尾
/^He/
Hello He He Heeee
// He
/llo$/
Heellllo llo
// llo
//開頭是 He 結尾是 llo,中間是任意字串
/^He.*llo$/g
Hello Hello
// Hello Hello
**i
不管大小寫**
Regular Expression 是 case sensitive 的特性,會區分大小寫,後面加上 i
可忽略大小寫:
/ha/g
HA HA ha ha HA
// ha ha
// 只會選到小寫 ha ha
/ha/gi
HA HA ha ha HA
// HA HA ha ha HA
// 大小寫都會選到
**|
或**
要特別注意的是,使用 OR 若第一個條件已經 match 到了,第二個條件就會直接被忽視:
/and|android/g
iOS and android
// and and
如果要正確 match 到 android,就要反過來寫,讓正規表達式可以先以第一個條件去 match 到 android,而不會像第一種寫法那樣因為已經被 and 條件 match 到而忽略:
/androd|and/g
iOS and android
// and android
範例
身分證字號:
/^[A-Z]\d{9}$/
A123456789
//但實際上身分證字號有一套演算法來判斷有效性
//上面的正規表達式只能簡易驗證格式符合而已
Gmail 信箱:
/^\w+@gmail\.com$/
example@gmail.com
// 開頭至少要有一個英數字 ^\w+
// @gmail 直接拿進來比對
// . 點部份要記得加 \ 來跳脫字元
// 最後是結尾為 .com 的,所以使用 .com$
搭配 JavaScript
字串取代
'banana'.replace(/na/, 'NA') // 'baNAna'
'banaNa'.replace(/NA/, 'na') // 'banana'
Capture Group
用 ()
來把一組表達式 match 到的內容捕獲成變數,方便之後引用、取代或做其他操作:
'apple'.match(/(a.)(p.)e/)
// $1 = 'ap'
// $2 = 'pl'
'apple'.replace(/(a.)(p.)e/, $1$2) // 'appl'
'apple'.replace(/(a.)(p.)e/, $2$1) // 'appl'
'2020/09/14'.match(/(.*)\/(.*)\/(.*)/)
// $1 = 2020
// $2 = 09
// $3 = 14
// 得到的陣列會有選到的字串,以及剛才選到的變數
// ['2020/09/14', '2020', '09', '14']
和 JSON.parse 搭配的取代
JSON.parse(
'2020/09/14'.repalce(
/(.*)\/(.*)\/(.*)/,
'{"year": "$1", "month": "$2", "day": "$3"}'
)
)
// {year: "$1", month: "$2", day: "$3"}
以上的案例都是比較簡單的,實際使用會需要考量很多 edge case,例如真正在驗證 email 的 Regular Expression 可能會長這樣:
function validateEmail(email) {
const re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(String(email).toLowerCase());
}
這種時候可以直接找現成的來用就好,讚讚!
總結
Regular Expression 除了可以用在 JavaScript 之外,也可以在 VSCode、Command Line 或其他環境上面使用,接下來再多多可以利用 Regexr.com 來多多熟悉和測試自己對它的了解~
參考資料:
簡易 Regular Expression 入門指南 by Huli
[線上讀書會] 承億 主講 regular expression
Regular Expressions (RegEx) Tutorial by The Net Ninja
正则基础