[JS] 簡單認識正規表達式 Regular Expression

[JS] 簡單認識正規表達式 Regular Expression

前言

這篇會來介紹正規表達式,第一次看到正規表達式時,只會想說這是什麼鬼…為何一小串就可以做完一般判斷式可能要寫好幾行的事。如果可以更深入了解活用的確可以在coding中幫助極大。因此這次我會藉由這篇讓我自己更釐清觀念。

介紹

正規表達式(Regular Expression, RegEx)是被用來匹配字串中字元組合的模式。
常搭配與這些字串方法(match、replace、search、split)來使用。

為什麼使用正則表達式?

> 用來測試字符串是否符合模式

可以用於驗證,像是電話,Email,信用卡號碼是否輸入正確

> 收尋匹配的字串

> 取代匹配到的字串

> 擷取出匹配到的字串

正則表達式使用規則

簡易字元

例如: /abc/

  • .replace(/abc/,’a’); 用’a’來取代匹配到的’abc’
  • strB 因為是abC的C為大寫,在/abc/後多加i則可以不管大小寫辨識到
  • strC 為ab c中有空白字元所以匹配不到
  • strD 在/abc/後多加g則可收尋到所有abc並且替換成a
1
2
3
4
5
6
7
8
9
let strA = 'Hi, do you know abc?';
let strB = 'The latest airplane designs evolved from slabCraft.';
let strC = 'Grab crab';
let strD = 'Hi abc, do you know abc?';

let resultA = strA.replace(/abc/,'a'); // Hi, do you know a?
let resultB = strB.replace(/abc/i,'a'); // The latest airplane designs evolved from slaraft.
let resultC = strC.replace(/abc/,'a'); // ab c中有空白字元所以匹配不到
let resultD = strD.replace(/abc/g,'a'); // Hi a, do you know a?

特殊字元

例如: /ab*c/

  • *代表b可以是零或多個,所以abbbbbbc或是ac都可以匹配到
1
2
let strA = 'Hi, do you know abbbbbbc ac abc bc?';
let resultA = strA.replace(/ab*c/g,'a'); // Hi, do you know a a a bc?


圖片出處: 網頁研習室

圖片解說
字元 解說
> 所有正規表示法規則都必須放到這兩者之間。
/^ 正規表示法的開始 /^A/則匹配A開頭的字元,例如Ant
$/ 正規表示法的結束 /A$/則匹配A結束的字元,例如nbA
[A-Z] [xyz] 字元的集合,等同於比對A到Z之間的任一大寫字母,例如[a-c]比對[abcd]這四個字母,[hcn]則比對h.c.n這三個字母
\d [0-9] 代表比對數字格式,兩者一樣。例如/\d/ 或 /[0-9]/ 在 “B2 is the number.” 中找到 ‘2’
{9} 樣式必須出現次數。例如/a{3}/ 無法在 “candy” 找到、但 “caaandy” 可以。[A-C]{2} 在A-C之間要符合兩次,”BA” “AC” “CA”…|
常用字元整理

中介字元 (Meta Character)

字元 解說
/^ 正規表示法的開始 /^A/則匹配A開頭的字元,例如Ant
$/ 正規表示法的結束 /A$/則匹配A結束的字元,例如nbA
. 小數點 匹配任何單一字元,換行除外,例如/.n/ 匹配「nay, an apple is on the tree」中的 an 和 on,但在「nay」中沒有匹配。

字元 解說
(x) 比對x並將符合的部分存入一個變數中,例如’aaa bbb’.replace(/(…) (…)/, ‘$2 $1’)則會得到’bbb aaa’對調結果
(?:x) 比對x並將符合的部分 不存入變數中
x(?=y) 正向肯定預查,符合後面接 y 的 x
x(?!y) 正向否定預查,符合後面不接 y 的 x
(?<=x)y 反向肯定預查,符合前面接 x 的 y
(?<!x)y 反向否定預查,符合後面不接 x 的 y

字元 解說
x|y x或者y
[A-Z] [xyz] 字元的集合,等同於比對A到Z之間的任一大寫字母,例如[a-c]比對[abcd]這四個字母,[hcn]則比對h.c.n這三個字母
[^xyz] 則與上方相反,比對不在[]內的任一字元。例如[^ecm]比對welcome則會找到w.l.o

字元 等價 解說
\d [0-9] 比對數字字元。例如/\d/ 或 /[0-9]/ 在 “B2 is the number.” 中找到 ‘2’
\D [^0-9] 比對非數字字元
\w [A-Za-z0-9_] 比對數字字母與底線的所有字元
\W [^A-Za-z0-9_] 比對不包含數字字母與底線的字元
\b 比對字元的邊界,例如空格 /\wB\b/比對’aaaB mbbA’找到aB,/\bmb/則找到第二行的’mb’
\B 比對非字元邊界
\s [ \f\n\r\t\v] 比對任何空白字元
\S [^ \f\n\r\t\v] 比對任何非空白字元
\f [\x0c\cL] 符合一個換頁符
\n [\x0a\cJ] 符合一個換行符
\r [\x0d\cM] 符合一個 Enter 符
\t [\x09\cI] 符合一個制表符
\v [\x0b\cK] 符合一個垂直制表符
\ 反斜線為避開特殊字元,若要表現\則須用兩個反斜線\\
\cX 控制字元,X 為 A-Z。也就是 Ctrl + [A-Z] 的意思

量詞 (Quantifier):限制符 指定匹配次數

字元 解說
* 樣式必須出現0次或多次(>0)。例如:/a*/
+ 樣式必須出現1次以上(>1)。例如:/a+/
? 樣式必須出現0或1次(0 or 1),等同於 {0,1},例如/a?b/可比對’Aab’的ab或是’Aa’的a * 如果同時使用 + ? 或 {},將會變成儘可能匹配最少的字元。例如:在「123abc」中應用 /\d+/ 可匹配「123」,但使用 /\d+?/ 在相同字串上只能匹配「1」
{n} 樣式必須出現n次。例如/a{3}/ 無法在 “candy” 找到、但 “caaandy” 可以。[A-C]{2} 在A-C之間要符合兩次,”BA” “AC” “CA”…|
{n,} 樣式至少符合出現n次。|
{n,m} 樣式出現次數必須介於n到m之間(n~m)

常見用法

功能 正規式
只能輸入數字 /^[0-9]*$/
只能輸入 n 位的數字 /^\d{n}$/
只能輸入至少 n 位的數字 /^\d{n,}$/
只能輸入 m~n 位的數字 /^\d{m,n}$/
只能輸入零和非零開頭的數字 /^(0|[1-9][0-9]*)$/
只能輸入有兩位小數的正實數 /^[0-9]+(.[0-9]{2})?$/
只能輸入有 1~3 位小數的正實數 /^[0-9]+(.[0-9]{1,3})?$/
只能輸入非零的正整數 /^+?[1-9][0-9]*$/
只能輸入非零的負整數 /^-[1-9][0-9]*$/
只能輸入長度為 3 的字符 /^.{3}$/
只能輸入由 26 個英文字母組成的字符串 /^[A-Za-z]+$/
只能輸入由 26 個大寫英文字母組成的字符串 /^[A-Z]+$/
只能輸入由 26 個小寫英文字母組成的字符串 /^[a-z]+$/
只能輸入由數字和 26 個英文字母組成的字符串 /^[A-Za-z0-9]+$/
只能輸入由數字、26 個英文字母或者下劃線組成的字符串 /^\w+$/
只能輸入漢字 /^[\u4e00-\u9fa5]{0,}$/
驗證用戶密碼(以字母開頭,長度在 6~18 之間,只能包含字符、數字和下劃線) /^[a-zA-Z]\w{5,17}$/
驗證 Email 地址 /^\w+([-+.]\w+)*@\w+([-.]\w+).\w+([-.]\w+)$/
驗證 InternetURL /^http://([\w-]+.)+[\w-]+(/[\w-./?%&=]*)?$/
驗證一年的 12 個月 /^(0?[1-9]
驗證一個月的 31 天 /^((0?[1-9])
驗證電話號碼 /^((\d{3,4}-)
驗證台灣身份證字號(1位大寫英文字母和首位數字1或2,共9位數字) /^[A-Z]{1}[1-2]{1}[0-9]{8}$/
驗證台灣手機電話號碼(09開頭的10個數字) /^09[0-9]{8}$/

驗證台灣電話號碼

/^([-_-—\s(]?)([(]?)((((0?)|((00)?))(((\s){0,2})|([-_-—\s]?)))|(([)]?)[+]?))(886)?([)]?)([-_-—\s]?)([(]?)[0]?[1-9]{1}([-_-—\s)]?)[1-9]{2}[-_-—]?[0-9]{3}[-_-—]?[0-9]{3}$/

可以用來驗證以下號碼
(02)3195693
0936957702
0987799756
0989861389
+886912345678
+886 2 12345678

驗證用戶密碼

長度在 6-18 之間,必須以英文字母開頭,其餘可使用英文字母、數字和下底線
/^[a-zA-Z]\w{5,17}$/

長度在 6-15 之間,必須包含至少一個大和小寫英文字、一個數字
/^(?=.\d)(?=.[a-z])(?=.*[A-Z]).{6,15}$/

移除字串中所有標點符號

1
2
let str=”jfkldsjalk,.23@#!$$k~!  @#$%^&*()(_ -=|\{}[]’;:,./<>??gg  g~“`gf”;
str = str.replace(/[\ |\~|\`|\!|\@|\#|\$|\%|\^|\&|\*|\(|\)|\-|\_|\ |\=|\||\\|\[|\]|\{|\}|\;|\:|\”|\’|\,|\<|\.|\>|\/|\?]/g,'');

判斷中英文字串的長度

因為中文佔兩個字元,英文佔1個字元,單純用.length判斷度不對,可使用下方正規式先做字元轉換

1
2
3
function getLength(str){
return str.replace(/[^\x00-\xff]/g,"**").length;
}

正規式測試用

Javascript 常搭配正規式的字串方法

.match()

會回傳一個符合比對的陣列

1
2
3
var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
var ary = str.match(/[A-E]/gi); //g比對回傳全部符合的 i不分大小寫
console.log(ary); // ['A', 'B', 'C', 'D', 'E', 'a', 'b', 'c', 'd', 'e']

.replace()

比對後取代

  • .replace(/abc/,’a’); 用’a’來取代匹配到的’abc’
  • strB 因為是abC的C為大寫,在/abc/後多加i則可以不管大小寫辨識到
  • strC 為ab c中有空白字元所以匹配不到
  • strD 在/abc/後多加g則可收尋到所有abc並且替換成a
1
2
3
4
5
6
7
8
9
let strA = 'Hi, do you know abc?';
let strB = 'The latest airplane designs evolved from slabCraft.';
let strC = 'Grab crab';
let strD = 'Hi abc, do you know abc?';

let resultA = strA.replace(/abc/,'a'); // Hi, do you know a?
let resultB = strB.replace(/abc/i,'a'); // The latest airplane designs evolved from slaraft.
let resultC = strC.replace(/abc/,'a'); // ab c中有空白字元所以匹配不到
let resultD = strD.replace(/abc/g,'a'); // Hi a, do you know a?

收尋與比對相符的字串後,回傳第一個字元的索引值,若沒有比對相符則回傳-1

1
2
3
const str="Visit the World!";
console.log(str.search(/world/i)); //10
console.log(str.search(/a/i)); //-1

.split()

比對符合的字元做為斷點來切割

1
2
3
var myString = "Hello 1 word. Sentence number 2.";
var splits = myString.split(/(\d)/); // 以數字為斷點切分成5段
console.log(splits); // [ "Hello ", "1", " word. Sentence number ", "2", "." ]

參考資料

[JS] 簡單認識正規表達式 Regular Expression

https://kaiyuncheng.github.io/2020/11/10/regularExpression/

Author

KaiYun Cheng

Posted on

2020-11-10

Updated on

2024-04-13

Licensed under

Comments

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×