JavaScript 語法 流程控制 Function (函數) Object (物件) 數值 布林值 字串 陣列 時間和日期 Math 物件
正規表示式 瀏覽器物件模型 BOM JS DOM HTML DOM CSS樣式 & Event

正規表示式 (Regular Expression)

正規表示式 (Regular Expression)

正規表示法,又稱正規表示式、正規表達式;英文 Regular Expression,簡稱 Regex, RegExp 或 RE。
正規表示法 (Regex) 是用來處理字串的方法,Regex 用自己一套特殊的符號表示法,讓我們可以很方便的搜尋字串、取代字串、刪除字串或測試字串是否符合樣式規則。

宣告 RegExp 物件 (Creating a regular expression)

在 JavaScript 中,你可以用 Regex literal 的方式來建立一個 Regex 物件。
語法:
 var pattern = /pattern/flags;        / / 用兩個斜線來包住正規表示式
例如:
 var re = /ab+c/;

或用  new RegExp 建構子 (constructor):
     var pattern = new RegExp(pattern, flags);
例如:
     var re = new RegExp('ab+c');

RegExp 物件內建的屬性 (Properties)

global
ignoreCase
lastIndex
multiline
source

RegExp 物件內建的方法 (Methods)

exec() 搜尋比對,符合傳回 Array(字串中匹配到的部分); 不符合傳回 null  var str="被比對的字串"; regexObj.exec(str)
test() 搜尋比對,符合傳回  true ; 不符合傳回 null                                          regexObj.test(str)

String 物件內建的 RegExp 相關方法

match()   搜尋比對,如果符合的正則表達式包含 g 修飾符,則以陣列傳回所有匹配到的字串;  str.match(regexp)
          不包含 g 修飾符,則傳回 Array ;  無符合傳回 null
search()    搜尋比對,符合傳回第一個相符的索引(index) ; 不符合傳回 -1         str.search(regexp)
replace()   取代字串,如果符合傳回一個新字串 ; 不影響原字串          str.replace(regexp, newstr)
簡單來說,當你想要看字串是否包含某pattern時,使用 test 或 search;想要更多的資訊(花較多耗效能),則使用 exec 或 match。

Regex 正規表示法 - 基本語法

一個 正規表示法 通常被稱為是一個 模式 (pattern),用來描述或匹配符合某個樣式規則的字串。
Regex 它不是一個程式語言,他只是一種「字串樣式規則」的「表示法」,用來表達字元符號在字串中出現的規則,大部分的程式語言都有支援 Regex 的用法,而任何工具只要支援這種表示法,你就可以在這工具上用 Regex 來處理字串。
pattern 一般由字符常量 (literal character constants) 和符號運算子 (operator symbols) 組成。
一個 pattern 中,常見的有下面這些組成元素:
字元:就是單純照字面上的意義。 例如 dog 可以用來匹配 dog 這字串;hello 101 則用來匹配 hello 101 這字串。
| 管線直線符號:或(or)的意思,用來將所有可能的選擇條件分隔開。例如 gray|grey 可以用來匹配 gray 或是 grey 字串。
() 小括號:群組 (grouping),用來表示作用範圍或優先順序。例如 gray|grey 和 gr(a|e)y 都同樣可以用來匹配 gray 或是 grey 字串。
量詞 (quantifier):quantifier 用來接在字符串或群組後面,表示某個條件應該出現「幾次」。 常見的量詞有:
    ?:表示連續出現 0 次或 1 次。例如 colou?r 可以用來匹配 color 或 colour。
    *:表示連續出現 0 次或多次。例如 ab*c 可以用來匹配 ac, abc, abbc, abbbc 或 abbbbbbc。
    +:表示連續出現 1 次或多次。例如 ab+c 可以用來匹配 abc, abbc, abbbc, abbbbbbc,但 ac 不符合。
    {min,max}:表示至少連續出現 min 次,但最多連續出現 max 次。  {m}:m次 。 {n,}:最少n次 。 {n,m}:n次到m次

   正則表達式 中可以利用的 特殊字符 完整列表以及描述:
字 元 解 說
\
反斜線放在非特殊符號前面,使非特殊符號不會被逐字譯出,代表特殊作用(轉義操作符)。
例如:'b' 如果沒有 '\' 在前頭,功能是找出小寫 b; 若改為 '\b' 則代表的是邊界功能,block 用意。
/\bter\b/.test("interest")   //false    /\bter\b/.test("in ter est")   //true
/a*/ 找出 0 個或是 1 個以上的 a;   而 /a\*/ 找出 'a*' 這個字串 
/aaaa*/g.test("caaady")   //true     /a\*/.test("caaady")   //false
'\' 也能使自身表現出來,表現 '\' ,必須以 '\\' 表達。  /[\\]/.test(">\\<")   //true
故   \\ 匹配「\」 , \/ 匹配「/」,  \* 匹配「*」
正則表達式 中的 特殊字元 :  /  \  ^  $  (  )  [  ]  {  }  .  *  +  ?  |  
但在 [ ](字元集合)當中 特殊字元 只有 5 個: ^  -  [  ]  \ 
加 脫逸字元 \ 在 特殊字元 前,使之以其原義表示
^ 匹配輸入字符串的 開始位置
例如:/^A/ 不會匹配「an A」的 A,但會匹配「An E」中的 A。
$ 匹配輸入字符串的 結束位置
例如:/t$/ 不會匹配「eater」中的 t,卻會匹配「eat」中的 t。
* 匹配前一字元 0 至多次。
舉例要求基本 'aaaa' ,'a*' 後面有 0 個或多個 a 的意思 /aaaaa*/g.test("caaady") //false
例如:/bo*/ 匹配「A ghost booooed」中的 boooo、「A bird warbled」中的 b,
但在 /bo*/ 匹配 「A goat grunted」中不會匹配任何字串。
+ 匹配前一字元 1 至多次,等同於 {1,}。
例如:/a+/ 匹配「candy」中的 a,以及所有「caaaaaaandy」中的 a。
? 匹配前一字元 0 至 1 次,等同於 {0,1}。
例如:/e?le?/ 匹配「angel」中的 el、「angle」中的 le、以及「solo」中的 l。
. (小數點)匹配除了換行符號"\n" 之外的單一字元。
例如:/.n/ 匹配「nay, an apple is on the tree」中的 an 和 on,但在「nay」中沒有匹配。
x|y 符合「x」或「y」。
舉例來說,/green|red/ 的話,會匹配 "green apple" 中的 "green" 以及 "red apple." 的 "red" 。
[xyz] 字符集合。匹配所包含的任意一個字符。 例如, '[abc]' 可以匹配 "plain" 中的 'a'。
若要設一個字元範圍的集合,可以使用橫線 "-" ,如下例所示: [a-d] 等同於 [abcd]。會匹配 "brisket" 的 "b" 、"city" 的 'c' ……等。
而 /[a-z.]+/ 和 /[\w.]+/ 均可匹配字串 "test.i.ng" 。 [a-z] 可以匹配 'a' 到 'z' 範圍內的任意小寫字母字符。
[^xyz] 負值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'。
而 [^abc]可以寫作[^a-c]. "brisket" 中找到 'r' 、"chop."中找到 'h'。
\b 匹配一個單詞邊界,也就是指單詞和空格間的位置。
例如, /er\b/ 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B 匹配非單詞邊界。
/er\B/ 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\d 匹配一個數字字符。等價於 [0-9]。
例如:/\d/ 或 /[0-9]/ 在 "B2 is the suite number." 中找到 '2'
\D 匹配一個非數字字符。等價於 [^0-9]。
例如:/\D/ 或/[^0-9]/ 在 "B2 is the suite number." 中找到 'B' 。
\s 匹配任何空白字符,包括空格、製表符、換頁符等等。等價於 [ \f\n\r\t\v]。
例如:/\s\w*/ 匹配 "foo bar." 中的 ' bar'
\S 匹配任何非空白字符。等價於 [^ \f\n\r\t\v]。
例如:/\S\w*/ 匹配 "foo bar." 中的 'foo'。
\w 匹配包括下劃線的任何單詞字符。等價於'[A-Za-z0-9_]'。
例如:/\w/ 符合 'apple'中的 'a' 、'$5.28 中的 '5' 以及 '3D' 中的 '3'。
\W 匹配任何"非"單詞字符。等價於 '[^A-Za-z0-9_]'。
例如:/\W/ 或是 /[^A-Za-z0-9_]/ 符合 "50%." 中的 '%'
\f 匹配一個換頁符。等價於 \x0c 和 \cL。
\n 匹配一個換行符。等價於 \x0a 和 \cJ。
\r 匹配一個回車符。等價於 \x0d 和 \cM。
\t 匹配一個製表符tab。等價於 \x09 和 \cI。
\cX 匹配由 x 指明的控制字符。 例如, \cM 匹配一個 Control-M 或回車符。
x 的值必須為 A-Z 或 a-z 之一。否則,將 c 視為一個原義的 'c' 字符。

(1)g 修飾符(flags)        /pattern/flags;        // 修飾符(flags) 置於 正規表示式 的最後
默認情況下,第一次匹配成功後,正則對象 就停止向下匹配了。
g 修飾符表示全局匹配(global),加上它以後,正則對象將匹配全部符合條件的結果,主要用於搜索和替換。
 var regex = /b/;
 var str = 'abba';
  regex.test(str);      // true
  regex.test(str);      // true
  regex.test(str);      // true
上面代碼中,正則模式不含g修飾符,每次都是從字符串頭部開始匹配。所以,連續做了三次匹配,都返回true。

 var regex = /b/g;
 var str = 'abba';
  regex.test(str);      // true
  regex.test(str);      // true
  regex.test(str);      // false
此代碼中,正則模式含有 g 修飾符,每次都是從上一次匹配成功處,開始向後匹配。
因為字符串abba只有兩個b,所以前兩次匹配結果為true,第三次匹配結果為false。

(2)i 修飾符
默認情況下,正則對象區分字母的大小寫,加上 i 修飾符以後表示忽略大小寫

(3)m 修飾符
m修飾符表示多行模式(multiline),會修改 ^ 和 $ 的行為。
默認情況下(即不加 m 修飾符時),^和$ 匹配字符串的開始處和結尾處,
加上 m 修飾符以後,^和$ 還會匹配行首和行尾,即 ^和$ 會識別換行符(\n)。
例如想要比對電話號碼是不是正確 :
var regrule = /^[0-9]{10}$/g;
var tel = '0900123456';
var myArray = regrule.test(tel);        //true
搭配 test()方法比對 tel 字串是否符合正則表達式的規則,如果符合就回傳 true,否則就回傳 false。
空值 與 錯誤 輸入
JS 中常見的幾種空值與錯誤輸入時的狀態:
輸入 NULL       console.log(regex.test(null));           執行結果:// false
輸入 空字串      console.log(regex.test(''));             執行結果:// false
輸入 undefined  console.log(regex.test(undefined));      執行結果:// false
輸入 NaN        console.log(regex.test(NaN));            執行結果:// false

匹配空行的正則表達式: \n[\s| ]*\r
匹配HTML標記的正則表達式: /<(.*)>.*<\/\1>|<(.*) \/>/ 
匹配首尾空格的正則表達式: (^\s*)|(\s*$)
代碼寫法 :
ex: var xxx = /best/;
    var yyy = "The best things";
    xxx.test( "The best things" );    // true  字符串中含有"best",所以 返回true
    xxx.test(yyy);                    // true  同上
    /best/.test( "The best things" )  // true  同上  (  /best/ 正規表達式"best" 放在 /  / 之間 )
    
常見例子 :
台灣手機驗證
let regex = new RegExp(/^09[0-9]{8}$|^09\d{2}-\d{6}$/)    請輸入: 

網址(URL)  /* 需要 http(s) protocol */
var regex = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/;
  
最少 6 位數字 (數字驗證)
let regex = new RegExp(/^[0-9]{6}$/)

4組 4位數字 (信用卡卡號驗證)
let regex = new RegExp(/^\d-\d-\d-\d$/)

帳號驗證
 條件為: 6 ~ 20 字中英文組成,開頭英文大寫,至少包含 1 個大小寫英文,至少包含 1 個數字
let regex = new RegExp(/^[A-Z]{1}(?=.*\d)(?=.*[a-zA-Z]).{6,20}$/)

密碼驗證
 條件為: 6 ~ 16 字中英文組成,至少包含 1 個大寫英文 與 小寫英文,至少包含 1 個數字
let regex = new RegExp(/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,16}$/)

Email 驗證
let regex = new RegExp(/^[^@\s]+@[^@\s]+\.[^@\s]+$/)   請輸入: