JavaScript
Regex
正則表達式(Regular Expression),常簡寫為 RegEx、RegExp 或 RE,代表描述一種字串匹配的模式(pattern)。在程式語言中,通常用來搜尋、比對、替換符合某個模式的文字。
在 JavaScript 中,Regex 常見使用情境如下:
舉個簡單的例子:「如何判斷某段資料內,是否包含字元 H
?」
可能就有以下三種解法:
let str = 'Hello World';
// 法一:跑迴圈
for (let i = 0; i < str.length - 1; i++) {
if (str[i] === 'H') {
return true;
}
}
// 法二:使用 indexOf
if (str.indexOf('H') !== -1) {
return true;
}
// 法三:正則表達式
if (new RegExp('H').test(str)) {
return true;
}
撰寫正規表達式,可透過以下兩種方式:
/ /
let reStr = /abc/
new RegExp()
let reStr = new RegExp('abc') // 查詢第一次匹配項目
在正規表達式中,某些特殊字元或符號屬於保留字:
以下為使用範例:
const str = 'The History of Hello World History'
str.match(/History/) // ['History', index: 4, ...
// ^:匹配輸入的開頭
str.match(/^History/) // null
// $:匹配輸入的結尾
str.match(/History$/) // ['History', index: 27...
// 使用反斜線 '\' 來跳脫特殊字元
const reg = /\$6/
reg.test('$666') // ture
*
、+
、?
、{}
預設情況下,一個字元只會匹配一次,搭配 *
、+
、?
、{}
字元可指定匹配次數:
*
:任意次數,等同於 {0,}
+
:至少一次(後面要跟著),等同於 {1,}
?
:零或一次(有或沒有),等同於 {0,1}
{m}
:m 次{m, n}
:從 m 到 n 次
const str = 'banana'
const regex = /ban/ // 符合 ban
const regex = /ba*n/ // ba, ban, baaan 均符合
const regex = /k?a/ // k 可有可無
const regex = /a+n/ // 必須包含 an
const regex = /an{2}/ // an 要包含 2 次
const regex = /an{2,4}/ // an 介於 2 到 4 次
const regex = /an{2,}/ // 2 次以上 an 均符合
i
、g
、m
而 i
、g
、m
這類標記(flag),不會寫在正則表達式裡,格式與範例如下:
/pattern/flags
let reStr = /abc/i // ignore:不區分大小寫
let reStr = new RegExp('abc', 'g') // global:全局匹配
可參考下圖,在 Regexr 網站的測試結果:
在 JavaScript 中,常與 RegExp 物件搭配使用的函式如下:
test()
、search()
exec()
、match()
replace()
const paragraph = 'Hello World';
const regex1 = /^He/g;
const regex2 = /Woooo/g;
console.log(regex1.test(paragraph)) // true
console.log(regex2.test(paragraph)) // false
const paragraph = 'Hello World';
const regex1 = /^He/g;
const regex2 = /Woooo/g;
console.log(paragraph.search(regex1)) // 0
console.log(paragraph.search(regex2)) // -1
const paragraph = 'Hello, I am fine. Thank you.';
const regex = /[A-Z]/;
const globalReg = /[A-Z]/g;
console.log(regex.exec(paragraph)); // ["H"]
console.log(globalReg.exec(paragraph)); // ["H"]
const paragraph = 'Hello, I am fine. Thank you.';
const regex = /[A-Z]/;
const globalReg = /[A-Z]/g;
console.log(paragraph.match(regex)); // ["H"]
console.log(paragraph.match(globalReg)); // ["H", "I", "T"]
const str = 'banana'
console.log(str.replace(/na/, 'NA')); // baNAna
console.log(str.replace(/n./, 'NA')); // baNAna '.' 代表任意字元
console.log(str.replace(/na/g, 'NA')); // baNANA
詳細規則可參考這篇:正則表示式 – 匹配規則
[a-z] // 匹配所有的小寫字母
[A-Z] // 匹配所有的大寫字母
[a-zA-Z] // 匹配所有的字母
[0-9] // 匹配所有的數字
[0-9\.\-] // 匹配所有的數字,句號和減號
^[a-z][0-9]$ // 匹配一個開頭為小寫字母,和一位數字組成的字串:e7
^[A-Z][0-9]{9} // 身分證字號(大寫英文 + 9 位數字):A123456789
[0-9]{10} // 手機號碼(10 位數字):0912345678
/\d{6}/ // 匹配 6 次任意數字:123456