Skip to content

Regex

正規表達式

正規表達式 Regular Expression (regex & regexp)

  • 是一種強大的文本處理工具,可以用來匹配、查找、替換文本中的特定模式。

  • 數據驗證:您可以使用正則表達式來驗證用戶輸入的數據是否符合特定的格式,例如電子郵件地址、電話號碼、郵政編碼等。

  • 搜索和替換:在文本編輯器或程式碼編輯器中,您可以使用正則表達式來進行複雜的搜索和替換操作。

  • 數據提取:如果您有一大段文本,並且想從中提取特定的信息(例如從日誌文件中提取錯誤消息),您可以使用正則表達式。

  • 文本分割:您可以使用正則表達式來分割文本。例如,您可以使用逗號加上任意數量的空格作為分隔符,來分割 CSV 文件。

符號 描述 範例 匹配
\ 轉譯 \. .
. 匹配任何單個字符(除了換行符) a.b "axb"、"a!b"、"a1b" 等
^ 匹配字符串的開頭 ^abc "abc"、"abcd",但不匹配 "xabc"
$ 匹配字符串的結尾 abc$ "123abc"、"xyzabc",
但不匹配 "abc123"
符號 描述 範例 匹配
\d 匹配任何數字(等同於 [0-9]) \d{3} "123"、"456" 等
\D 匹配任何 非數字字符 (等同於 [^0-9]) \D{2} "ab"、"!@" 等
\w 匹配任何字母、數字或下劃線
(等同於 [a-zA-Z0-9_])
\w+ "hello"、"world_123" 等
\W 匹配任何非字母、非數字和非下劃線字符
(等同於 [^a-zA-Z0-9_])
\W{2} "!@"、"#%" 等
\s 匹配任何空白字符
(包括空格、制表符、換行符等)
\s+ " "、"\t"、"\n" 等
\S 匹配任何非空白字符 \S{3} "abc"、"123" 等
[abc] 匹配方括號中的任何字符
(在這裡是 a、b 或 c)
[abc]+ "a"、"abc"、"ba" 等
[^abc] 匹配除方括號中的字符以外的任何字符
(在這裡是除 a、b 和 c 以外的任何字符)
[^abc]+ "def"、"xyz" 等
(abc|def) 匹配括號中的任何一個選項
(在這裡是 "abc" 或 "def")
(abc|def) "abc" 或 "def"
限定符 描述 範例 匹配
{n} 匹配前面的元素恰好 n 次 a{2} "aa"
{n,} 匹配前面的元素至少 n 次 a{2,} "aa", "aaa", "aaaa", ...
{n,m} 匹配前面的元素至少 n 次,但不超過 m 次 a{2,3} "aa", "aaa"
* 匹配前面的元素零次或多次 a* = a{0,} "", "a", "aa", "aaa", ...
+ 匹配前面的元素一次或多次 a+ = a{1,} "a", "aa", "aaa", ...
? 匹配前面的元素零次或一次 a? = a{0,1} "", "a"

1.用一個字串表達以下網址

transbiz.com.tw/post55688/text
transbiz.com.tw/post58588/text
transbiz.com.tw/post25252/text

解答
/transbiz\.com\.tw\/post\d{5}\/text/g

2.用一個字串表達下列所有IP

192.141.9.3
192.141.7.3
192.141.4.3

解答
/192\.141\.\d\.3/g

3.用一個字串表達下列所有網址

transbiz.com.tw/fb/post01
transbiz.com.tw/fb/post02
transbiz.com.tw/fb/post03
transbiz.com.tw/web/post01
transbiz.com.tw/web/post02
transbiz.com.tw/web/post03

解答
/transbiz.com.tw\/(fb|web)\/post0\d/g

例子 Regex101

身分證字號

/^[A-Za-z][12]\d{8}$/gm 
詳解

[A-Za-z] = 大小寫英文字母
[12] = 1或2
\d{8} = 8碼數字

西元生日

/^\d{4}[-\/\s](0[1-9]|1[0-2])[-\/\s](0[1-9]|1\d|2\d|3[01])/gm
詳解

\d{4} = 0000~9999
[-\/\s] = 使用者可以輸入-/空格 已表示日期分隔
(0[1-9]|1[0-2]) = 01~0910~12
(0\d|1\d|2\d|3[01])
01~0910~1920~2930~31

電子信箱

/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/gm
Note

這個正則表達式的解釋如下:
^:開始匹配輸入的開頭。
[a-zA-Z0-9._%+-]+:匹配一個或多個字母、數字、點、下劃線、百分號、加號或破折號。這部分對應電子郵件地址的用戶名部分。
@:匹配 '@' 符號。
[a-zA-Z0-9.-]+:匹配一個或多個字母、數字、點或破折號。這部分對應電子郵件地址的域名部分。
.:匹配點符號,這個點符號分隔域名和頂級域名。
[a-zA-Z]{2,}:匹配兩個或更多的字母。這部分對應電子郵件地址的頂級域名部分(例如 '.com'、'.net'、'.org' 等)。
$:結束匹配輸入的結尾。

網址URL

/^(https:\/\/www.|https?:\/\/|www\.)(((?!-)(?!.*--)[a-zA-Z0-9-]+(?<!-))+\.)+(?<!-)[a-z]{2,}(\/[a-zA-Z0-9-\/\?\=\+\&\#\.]*)?(?<!-)$/gm 
詳解

^:開始匹配輸入的開頭。
(https:\/\/www.|https?:\/\/|www\.):匹配 https://www.、http://、https:// 或 www.。這部分對應網址的協議和可選的 www 子域名。
(((?!-)(?!.*--)[a-zA-Z0-9-]+(?<!-))+\.)+:匹配一個或多個由字母、數字或破折號組成的子域名或域名,
但是不能以破折號開頭或結尾,也不能包含連續的破折號。每個子域名或域名後面都有一個點號。
(?<!-)[a-z]{2,}:匹配兩個或更多的小寫字母。這部分對應網址的頂級域名(例如 .com、.net、.org 等),並且不能以破折號結尾。
(\/[a-zA-Z0-9-\/\?\=\+\&\#\.]*)?:可選部分,匹配由字母、數字、破折號、斜線、問號、等號、加號、和號、井號或點號組成的路徑、查詢參數或錨點。
$:結束匹配輸入的結尾。
/gm:這是正則表達式的標誌。
'g' 表示全局匹配(匹配輸入中的所有符合條件的部分),
'm' 表示多行匹配('^''$' 會匹配每一行的開頭和結尾,而不只是整個輸入的開頭和結尾)。

創建正則表達式的方法

let pattern = 'abc';
let flags = 'g';
let regex = new RegExp(pattern, flags);
let regex2 = new RegExp('abc', 'g');
let regex = /abc/g;

旗標

標誌 描述
/i 不區分大小寫
/g 全局匹配
/m 多行匹配
/u Unicode碼點
/y 黏性匹配
/s dotAll .表示任何字符包含換行或換頁符

ingoreCase

/i = 不區分大小寫
const regex = /hello/i;
console.log(regex.test("Hello")); // true

global

/g = 全局匹配
const regex = /test/g;
console.log("test test".match(regex)); // ["test", "test"]

multiline

/m = 多行匹配
const regex = /^start/gm;
console.log("start\nstart".match(regex)); // ["start", "start"]

Sticky matching

每次匹配後,它會從上次匹配結束的位置開始下一次匹配。

/y = 黏性匹配
const text = 'test1 test2 test3';
const regex = /\w+\s/y;
console.log(regex.lastIndex);  // 0
console.log(regex.exec(text)); // ["test1"]
console.log(regex.lastIndex);  // 6
console.log(regex.exec(text)); // ["test2"]
console.log(regex.lastIndex);  // 12
regex.lastIndex = 0;
console.log(regex.lastIndex);  // 0
console.log(regex.exec(text)); // ["test1"]

Unicode

Unicode參考

/u = Unicode
const regex = /\u{1F603}/u;
console.log(regex.test("😃")); // true

console.log('xyz林123'.replace(/\u6797/, 'Lin'))  
//xyzLin123
console.log('xyz林123'.replace(/\u{6797}/, 'Lin'))
//xyz林123
console.log('xyz林123'.replace(/\u{6797}/u, 'Lin'))
//xyzLin123

/\p{}/u
符號 描述 範例 匹配
\p{L} 匹配任何字母 \p{L}{3} "abc"、"def" 等
\p{N} 匹配任何數字 \p{N}{3} "123"、"456" 等
\p{P} 匹配任何標點符號 \p{P}{2} "!@"、"#%" 等
\p{Z} 匹配任何分隔符(包括空格、制表符、換行符等) \p{Z}+ " "、"\t"、"\n" 等
\p{S} 匹配任何符號(非字母、非數字、非標點、非分隔符) \p{S}{2} "$%"、"&*" 等
\p{Lu} 匹配任何大寫字母 \p{Lu}{2} "AB"、"CD" 等
\p{Ll} 匹配任何小寫字母 \p{Ll}{2} "ab"、"cd" 等
\p{Nd} 匹配任何十進制數字 \p{Nd}{3} "123"、"456" 等
const str = "A ბ ㄱ"
console.log( str.match(/\p{L}/gu) )
console.log( str.match(/\p{L}/g) )

參考資料 Regex101