參考網站
建立正規式 正則表達式的規則稱作 pattern 。在 JavaScript 中可以透過 Regular expression literals 的方式或建構式的方式來建立 regular expressions pattern:
方法一:Regular expression literals script 載入時即編譯,當 pattern 不會改變時,使用此方式定義 pattern 效能較好。 方法二:Function Constructor 程式執行過程才會被編譯,效能較差,適合用在 regular expression pattern 可能會改變時使用。 1
2
var re = new RegExp ( 'ab+c' );
var myRe = new RegExp ( 'd(b+)d' , 'g' );
Copy Regular expression literals
效能較好,適合 pattern 不會改變的情況;Function Constructor
效能較差,適合用在 pattern 可能動態改變的情況。
使用正規式 在 JavaScript 中可以使用正規式的函式包含:
RegExp.prototype.test()
:搜尋字串中是否有符合的部分,回傳 true/false。RegExp.prototype.exec()
:以陣列回傳字串中匹配到的部分,否則回傳 null。String.prototype.match()
:以陣列回傳字串中匹配到的部分,否則回傳 null。String.prototype.replace()
:尋找字串中匹配的部分,並取代之。String.prototype.search()
:尋找字串中是否有符合的部分,有的話回傳 index,否則回傳 -1。String.prototype.split()
:在字串根據匹配到的項目拆成陣列。簡單來說,當你想要看字串是否包含某 pattern 時,使用 test
或 search
; 想要更多的資訊(花較多耗效能),則使用 exec 或 match。
特殊字元 (character) 標籤(flag) 1
2
3
regex = /hello/ ; // 區分大小寫,匹配 "hello", "hello123", "123hello123", "123hello",但不匹配 "hell0", "Hello"
regex = /hello/i ; // 不區分大小寫,匹配 "hello", "HelLo", "123HelLO"
regex = /hello/g ; // 全域搜尋
Copy ES 2019 新增 /s
的標籤,過去 .
可以用來匹配除了換行符號以外(\n
, \r
)的所有字元:
1
2
3
// 過去 . 可以匹配到除了「換行符號」以外的所有字元
console . log ( /./ . test ( '\n' )); // → false
console . log ( /./ . test ( '\r' )); // → false
Copy 過去雖然可以使用 [\w\W]
來匹配到換行符號,但這不是最好的做法:
1
2
console . log ( /[\w\W]/ . test ( '\n' )); // → true
console . log ( /[\w\W]/ . test ( '\r' )); // → true
Copy 在 ES 2019 中,只要最後有標記 /s
的標籤,如此 .
將也能夠匹配到換行符號:
1
2
console . log ( /./s.test('\n')); // → true
console . log ( /./s.test('\r')); // → true
Copy 普通字元 //
1
2
var regex = /a/ ;
var regex = /is/ ;
Copy 反斜線 \
1
2
3
4
5
6
/* 在「非」特殊字元前面使用反斜線時,表示要把反斜線後的字當作是特殊字元 */
var regex = /\b/ ; // b 原本不是特殊字元,這個 b 要當成特殊字元
/* 在特殊字元前面使用反斜線時,表示要把反斜線後的字當作是「非」特殊字元 */
var regex = /if\(true/ ; // ( 原本是特殊字元,但這裡要當成非特殊字元
var regex = /1\+2=3/ ; // + 原本是特殊字元,但這裡要當成非特殊字元
Copy 任意一個字元 .
1
2
3
var regex = /a.man/ ; // a*man 都會 match,例如 "acman", "awman", 但 "a\nman" 無法匹配。
var regex = /.a/ ; // 任何一個字元後加上 a
Copy 多個字元 []
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 小寫 a 或大寫 A
var regex = /[aA]/ ;
// 匹配所有不是 a 或 A 的字
var regex = /[^aA]/ ;
// a, e, i, o, u 都會 match
var regex = /[aeiou]/ ;
// 英文字母
var regex = /[a-z]/ ; // 所有小寫的字母,從小寫 a 到小寫 z
var regex = /[A-Z]/ ; // 所有大寫的字母,從大寫 A 到大寫 Z
var regex = /[a-zA-Z]/ ; // 所有英文字母
// 數字 5 ~ 8
var regex = /[5-8]/ ;
Copy 括號 ()
1
2
3
var regex = /^a|^the|^an/ ; // 套用到裡面所有的
var regex = /^(a|the|an)/ ; // 等同於
Copy 不是(除了) ^
1
2
3
4
5
/* 不是 a 都會 match */
var regex = /[^a]/ ;
/* 不是數字都會 match */
var regex = /[^0-9]/ ;
Copy 多個字元縮寫 keywords:\d 、\w 、\s 、\b 、\D 、\W 、\S \d : digit,[0-9]
\w : word,包含英文大小寫、數字、底線,[A-Za-z0-9_]
\s : space,包含 space, tab, form feed, line feed,[\f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]
\D : 不是 digit,等同於 [^\d]
\W : 不是 word,等同於 [^\w]
\S : 不是 space,等同於 [^\s]
1
2
3
4
5
6
7
8
9
10
/* 所有 word + e */
var regex = /\we/ ;
/* 連續兩個任意的數值 */
var regex = /\d\d/ ;
/* 句子中結尾為 s 的單字 */
var regex = /s\b/ ;
var regex = /\b[a-z]/g ; // 句子中各個單字的第一個字母
Copy 其他特殊字元: \t : tab\b : word boundary,用來比對單字和單字間的空白,/s\b/
則會比對句子中最一個字母是 s 的單字Word boundary \b 、\B 透過 \b
可以配對 word boundary ,word boundary 指的是一個字元的前後沒有其他任何字元。
要注意 \b
和 [\b]
是不一樣的,[\b]
是用來配對 backspace。
1
2
3
// is 這個單字才會被選到,Th`is` 的 is 不會
let matchedResult = 'This is an apple.' . match ( /\bis\b/ );
// [ 'is', index: 5, input: 'This is an apple.' ]
Copy 相反地,\B
則是 non-word boundary :
Before the first character of the string, if the first character is not a word character. After the last character of the string, if the last character is not a word character. Between two word characters Between two non-word characters The empty string 1
2
3
4
// 使用 \B 會配對到 This 中的 is
let matchedResult = 'This is an apple.' . match ( /\Bis/ );
// [ 'is', index: 2, input: 'This is an apple.' ]
Copy 出現次數 * + ? {} {, }
keywords: * 、+ 、? 、{次數} 、{最少次數, 最多次數} * : 任意次數,等同於{0,}
+ : 至少一次(後面要跟著),等同於 {1,}
? : 零或一次(有或沒有),等同於 {0,1}
{次數} {最少次數, 最多次數} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var regex = /abc/ ; // 找到符合 "abc"
var regex = /ab*c/ ; // *表示前一個單字可以是 0 個或多個,因此 ac, abc, abbbbc 都符合規則
var regex = /n?a/ ; // n 可有可無
var regex = /a{2}/ ; // a 要 2 次,所以會是 a
var regex = /a{2,4}/ ; // a 介於 2 次到 4 次之間
var regex = /a{2,}/ ; // 2 次以上的 a 都可以,大括號後面不要有空格
var regex = /(hello){4}/ ; // 4 次的 hello,hellohellohellohello
var regex = /\d{3}/ ; // 3 次的數字
Copy 開頭與結尾 keywords:^ 、$ 1
2
3
4
5
6
7
8
9
10
11
12
/* 以 A 開頭的字才會匹配到 */
/^A/gm . test ( 'Abc' ); // true
/^A/gm . test ( 'bac' ); // false
/* 開頭有 He */
var regex = /^He/ ;
/* 結尾有 llo */
var regex = /llo$/ ;
/* 開頭 He 結尾 llo 中間任意字元可以有任意次數 */
var regex = /^He.*llo$/ ;
Copy 或 |
1
2
3
4
5
// and 或 android,match 到 `and`roid 就不 match `android`
var regex = /and|android/ ;
// match 到 android 還是會 match and
var regex = /android|and/ ;
Copy LookAround Assertions keywords: x(?=y) 、x(?!y) Lookahead assertions: x(?=y)
、x(?!y)
Lookbehind assertions: (?<=y)x
、(?<!y)x
Look Ahead 1
2
3
4
5
6
7
8
9
10
11
12
// foo(?=bar),foo 後面要跟著 bar 才會配對到 foo
const regexp = /foo(?=bar)/ ;
regexp . exec ( 'foo' ); // null
regexp . exec ( 'bar' ); // null
regexp . exec ( 'foobar' ); // [ 'foo', index: 0, input: 'foobar', groups: undefined ]
// foo(?!bar),foo 後面不能跟著 bar,如此才會配對到 foo
const regexp = /foo(?!bar)/ ;
regexp . exec ( 'foo' ); // [ 'foo', index: 0, input: 'foo', groups: undefined ]
regexp . exec ( 'foo123' ); // [ 'foo', index: 0, input: 'foo123', groups: undefined ]
regexp . exec ( 'bar' ); // null
regexp . exec ( 'foobar' ); // null
Copy Look Behind ?<= :前面需要跟著才會匹配到?<! :前面不能跟著才會匹配到 1
2
3
4
5
6
7
8
9
10
11
12
// (?<=foo)bar,當 bar 前面有 foo 時才會配對到 bar
const regexp = /(?<=foo)bar/ ;
regexp . exec ( 'foo' ); // null
regexp . exec ( 'bar' ); // null
regexp . exec ( 'foobar' ); // [ 'bar', index: 3, input: 'foobar', groups: undefined ]
// (?<!foo)bar,當 bar 前面沒有 foo 時才會配對到 bar
const regexp = /(?<!foo)bar/ ;
regexp . exec ( 'foo' ); // null
regexp . exec ( 'bar' ); // [ 'bar', index: 0, input: 'bar', groups: undefined ]
regexp . exec ( '123bar' ); // [ 'bar', index: 3, input: '123bar', groups: undefined ]
regexp . exec ( 'foobar' ); // null
Copy ❗❗❗ Lookbehind assertions 屬於 ES2018 的語法,須注意相容性。 ❗❗❗
貪婪模式(Greedy Mode) 預設會啟用貪婪模式,如果想要關閉貪婪模式,也就是讓到一匹配到就停止,可以使用在 *
、 +
等後面加上 ?
,例如 .*?
、.+?
。
pattern 筆記 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
export default {
// 允許數字、英文字
// 長度4~12
account : /^[0-9A-Za-z]{4,12}$/ ,
// 需包含數字、英文字、英文特殊符號
// 但不得包含符號 \
// 長度1~24
password : /^(?=.*\d)(?=.*[a-zA-Z])[a-zA-Z0-9!@#$%^&*()_+{}:"|<>?\-=\[\]'\;,./~`]{1,24}$/ ,
// 允許數字、英文字、中文字
// 長度2~8
nickName : /^[0-9A-Za-z\u4E00-\u9FFF]{2,8}$/ ,
// 允許數字、英文字、中文字、英文特殊符號、空白,但開頭不得為特殊符號或空白
realName : /^(?!(-))(?!(\s))(?!(,))[A-Za-z\-\,\s\u4E00-\u9FFF]{0,20}[^(?=(!@#$%^&*()_+{}:"|<>?\-=\[\]'\;,./~\s\d`)))]$/ ,
// 信箱
createEmail : /^([\w])([\-\._]?[\w]){0,64}\@([\w])([\-\._]?[\w]){0,64}\.([a-zA-Z]){2,6}$/ ,
// 前三碼英文字、後三碼數字
promotionCode : /^[A-Za-z]{3}[0-9]{3}$/ ,
// 允許數字、英文字、中文字、英文特殊符號、中文特殊符號、空白
// 長度0~100
remark : /^[0-9A-Za-z-_\u4E00-\u9FA5+/.*!@#$%&?()=|':;<>,~!@#¥……&*()——|{}【】‘;:”“'。,、?%\s]{0,100}$/ ,
}
Copy