### 正则:正则是匹配模式:要么匹配字符,要么匹配位置
```
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. 相关案例