### 正則:正則是匹配模式:要么匹配字符,要么匹配位置
```
1. 正則表達式之所以強大,是因為其可以模糊匹配,模糊匹配可以分為橫向與縱向匹配模式
2. 橫向模糊匹配:是指可匹配的字符串的長度是不固定的,實現方案是:量詞 { n, m }
3. 縱向模糊匹配:是指可匹配的字符串具體到某一位的時候,它可以不是具體的某一個,比如:[ abc ]
```
### 字符組
```
1. 只匹配其中一個值:[ abc ]
2. 范圍表示法:[ 123456abcdeABCDE ]:范圍簡寫:[ 1-6a-eA-E ]
3. 匹配特殊值:[ -az ] || [ az- ] || [ a\-z ]:匹配:a - z,轉義-號或者放在前后
4. 排除字符組:[ ^abc ]
```
### 常見的簡寫形式
```
1. \d:[ 0-9 ]:表示一位數字
2. \D:[ ^0-9 ]:除數字外的任意字符
3. \w:[ a-zA-Z0-9_ ]:單詞字符:大小寫字母數字下劃線
4. \W:[ ^a-zA-Z0-9_ ]:除單詞字符外的任意字符
5. \s:[ \t\v\n\r\f ]:空白字符:包括空格、水平制表符、垂直制表符、換行符、回車符、換頁符
6. \S:[ ^ \t\v\n\r\f ]:非空白字符
7. .:[ ^\n\r\u2028\2029 ]:通配符:表示幾乎任意字符,除了換行符、回車符、行分隔符和段分隔符除外
```
### 匹配任意字符
```
1. [ \d\D ] || [ \s\S ] || [ \w\W ] || [ ^ ]
```
### 量詞:共五個,默認貪懶模式
```
1. { m }:表示m次
2. { m, }:表示至少出現m次
3. ?:表示出現0或1次,等于 { 0, 1 }
4. + :表示至少出一次,等于 { 1, }
5. * :表示出現任意次,等于 { 0, }
```
### 貪懶模式與惰性模式:在量詞后添加?更換為惰性模式
```
1. 貪懶模式:在量詞范圍內盡量多的去匹配
```
```
let str = "123 1234 12345 45678"
let reg = /[\d]{2,5}/g
str.match( reg ) //["123", "1234", "12345", "45678"]
```
```
2. 惰性模式:在量詞范圍內按最少的去匹配
```
```
let str = "123 1234 12345 45678"
let reg = /[\d]{2,5}?/g
str.match( reg ) //["12", "12", "34", "12", "34", "45", "67"]
```
### 分支匹配:| 管道符分割 m 多行匹配
1. reg1 | reg2
### 案例
1. 匹配ID
```
let str = "<div id='container' class='main'></div>"
let reg = /id='[^']*'/g
str.match( reg ) // ["id='container'"]
```
2. 匹配換行
```
let str = "hello\nworld"
let reg = /^|$/gm
str.replace(reg, "#") // #hello#
#world#
```
3. 為數字加上,號 -- 排隊最前面的位置
```
let str = "1234567891"
str.replace(/(?=(\d{3})+$)/g, ",") // 1,234,567,891
let str = "234567891"
str.replace(/(?!^)(?=(\d{3})+$)/g, ",") // 234,567,891
```
### 匹配位置:六個位置字符:^ $ \b \B ( ?=p ) ( ?!p )
1. 單詞邊界:\b:\w與\W、\w與^、\w與$之間的位置
```
let str = "[JS] hello.world,I'm Jack!"
let reg = /\b/g
str.replace(reg, "#") //"[#JS#] #hello#.#world#,#I#'#m# #Jack#!"
```
2. 非單詞邊界:\B:\b的相反
```
let str = "[JS] hello.world,I'm Jack!"
let reg = /\B/g
str.replace(reg, "#") //"#[J#S]# h#e#l#l#o.w#o#r#l#d,I'm J#a#c#k!#"
```
3. ( ?=p ):表示p前面的位置
```
var result = "hello".replace(/(?=l)/g, '#');
console.log(result); // he#l#lo
```
4. ( ?!p ):表示不等于p前面的位置
```
var result = "hello".replace(/(?!l)/g, '#');
console.log(result); // #h#ell#o#
```
5. ^ :匹配開頭
6. $ :匹配結束
### 正則中括號的作用
1. 分組和分支結構:(ab)+ && (p1|p2)
```
let str = "abc abab abcabab"
let reg = /(ab)+/g
str.match(reg) // ["ab", "abab", "ab", "abab"]
```
2. 分組引用
```
const reg = /(\d{4})-(\d{2})-(\d{2})/
const str = "2019-02-18"
str.match(reg) // ["2019-02-18", "2019", "02", "18", index: 0, input: "2019-02-18", groups: undefined]
str.match(reg) // ["2019-02-18"] 正則中有g時的表現形式,只全規則匹配
match方法,先全局正則匹配,再單個分組匹配,匹配下標,輸入字符
正則方法調用后可使用構造函數的全局屬性$1-$9來獲取
RegExp.$1:2019
RegExp.$2:02
RegExp.$3:18
$2$3$1相當于括號中的分組匹配結果
str.replace(reg, "$2+$3+$1") // 20+18+2019
```
3. 反向引用:\1\2\3匹配之前的分組,\2表示完全匹配第二個括號內的規則
```
const reg = /(\d{4})(-|\.|\/)(\d{2})\2(\d{2})/g
const str = "2019-02-18"
const str2 = "2019-02/18"
str.match(reg) // ["2019","02","18"]
str2.match(reg) // null,/與-無法匹配
const rge2 = /^((\d)(\d(\d)))\1\2\3\4$/:括號嵌套,由外層往內查找,內層由左往右
const regex = /(\d)+ \1/:加了括號匹配最后一位數
regex.test("12345 1") // => false
regex.test("12345 5") // => true
```
4. 非捕獲括號
5. 相關案例