16正则表达式
# 正则表达式
# 一、正则表达式字符匹配
# 创建正则表达式
var reg = /hello/ //字面量创建
console.log(reg);
var reg = new RegExp(hello)//构造函数创建
2
3
# 正则表达式方法
# 1)test (正则方法)🏳🌈
正则 在前面 字符串 在后面
检测出该字符串是否符合正则表达式
var str = "hello" //原生
var reg = /hello/
console.log(reg.test(str)); //true
2
3
# 在hello外面new一个数
var str = "hello我是在外面new一个" //在外面就可以
var reg = /hello/
console.log(reg.test(str)); //true
2
3
# 在hello里面new一个数
var str = "hell我是在里new一个o" //在里面就不可以了
var reg = /hello/
console.log(reg.test(str)); //false
2
3
# 2) search (字符串方法)
字符串 在前面正则 在后面
检索 出字符串符合正则的字符的索引值
var str = "hello world"
var reg = /world/
console.log(str.search(reg));//6
2
3
# 3) match(字符串方法)
字符串 在前面正则 在后面
在字符串中搜索符合规则的内容,搜索成功就返回内容,格式为数组,失败就返回null
var str = "hello world"
var reg = /l/
console.log(str.match(reg));
//["l", index: 2, input: "hello world", groups: undefined]
2
3
4
var str = "hello world"
var reg = /p/ //p不在字符串中就会返回null
console.log(str.match(reg));//null
2
3
# 4) exec(正则方法) 🏳🌈
正则 在前面 字符串 在后面
在字符串中搜索符合规则的内容,搜索成功就返回内容,格式为数组,失败就返回null
var str = "hello world"
var reg = /l/
console.log(reg.exec(str));
//["l", index: 2, input: "hello world", groups: undefined]
2
3
4
# 5) replace(字符串方法)
字符串 在前面*正则* 在后面
查找符合正则的字符串,就替换成对应的字符串。返回替换后的内容
var str = "hello world"
var reg = /o/
console.log(str.replace(reg, "a")); //hella world
2
3
加个g就可以替换后面的o咯
var str = "hello world"
var reg = /o/g //这里加个g就可以替换后面的o咯
console.log(str.replace(reg, "a")); //hella warld
2
3
# 案例
打印出hello world里面每一个l的索引值
var str = "hello world"
var reg = "l"
var arr = str.split("")//转换数组
// console.log([...new Set(arr)]);//这里是可以去重
//["h", "e", "l", "o", " ", "w", "r", "d"]
arr.forEach(function (item, idx) {
if (item === reg) {
console.log(idx); //2,3,9
}
})
2
3
4
5
6
7
8
9
10
# 修饰符
# 1) 加的【i】
var str = "hello world"
var reg = /HELLO/
console.log(reg.test(str));//false
2
3
i可以让正则对大小写不敏感
var str = "hello world"
var reg = /HELLO/i
console.log(reg.test(str));//true
2
3
# 2 )加的【g】🐱👤
g可以让正则匹配 所有 的字符串
var str = "hello wold"
var reg = /l/g
console.log(str.match(reg));//(3) ["l", "l", "l"]
2
3
# 3) 加的【m】
m可以匹配换行注意:
只有当目标*字符串* 含有**\n** 【\n是换行哦】
而且*正则表达式* 中含有**^或$的时候,/m**修饰符才有作用
var str = "a0b\na1b\na2b\na3b\na4b"
var reg = /^a[1-3]b$/m
console.log(reg.test(str));//true
2
3
# 纵向模糊匹配🚓
纵向模糊指的是,一个正则匹配的字符串,具体到某一位字符时,它可以不是某个确定的字符,可以有多种可能。
let str = "a1b a2b a3b a4b a5b"
let reg = /a[12345]b/g
console.log(str.match(reg))//["a1b", "a2b", "a3b"]
2
3
# 1、字符组
需要强调的是,虽叫字符组(字符类),但只是其中一个字符。例如[abc],表示匹配一个字符,它可以是“a”、“b”、“c”之一。
# 1) 范围表示
如果字符组里的字符特别多的话,怎么办?可以使用范围表示法。
//匹配a20 a30 a40
let str = "a10 a20 a30 a40 a50"
let reg = /a[2-4]0/g
console.log(str.match(reg))
//匹配b c d
let str = "a b c d e"
let reg = /[b-d]/g
console.log(str.match(reg))
//匹配所有的数字
let str = "1 2 3 4 5"
let reg = /[0-9]/g
console.log(str.match(reg))
//匹配所有的大小写英文字母
let str = "a b c d e A B C D"
let reg = /[A-Za-z]/g
console.log(str.match(reg))
//匹配 a - z
let str = "a - z"
let reg = /[a\\-z]/g 或 /[az-]/g 或 /[-az]/g
console.log(str.match(reg))
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
练习中💨
数字匹配
var str = "5.5"
var reg = /[1-9]/
console.log(reg.test(str));//true
var str = "1000"
var reg = /[1-9]/
console.log(reg.test(str));//true
var str = "55000"
var reg = /[1-9]/
console.log(reg.test(str));//true
2
3
4
5
6
7
8
9
10
11
英文匹配
var str = "d"
var reg = /[a-z]/
console.log(reg.test(str));//true
// 英文大小写
var str = "A"
var reg = /[A-Ca-c]/
console.log(reg.test(str));//true
var str = "D"
var reg = /[A-Ca-c]/
console.log(reg.test(str));//false
2
3
4
5
6
7
8
9
10
11
12
13
# 2) 排除字符组
纵向模糊匹配,还有一种情形就是,某位字符可以是任何东西,但就不能是"a"、"b"、"c"。
//匹配除了abc以外的英文字母
let str = "d e f g h i j k"
let reg = /[^abc]/g
console.log(str.match(reg))
2
3
4
练习中💨
取反
var str = "d"
var reg = /[^abc]/
console.log(reg.test(str));//true
var str = "a"
var reg = /[^abc]/
console.log(reg.test(str));//false
var str = "c"
var reg = /[^abc]/
console.log(reg.test(str));//true
2
3
4
5
6
7
8
9
10
11
# 3) 字符组简写
\\d就是[0-9]。表示是一位数字。
\\D就是[^0-9]。表示除数字外的任意字符。
\\w就是[0-9a-zA-Z_]。表示数字、大小写字母和下划线。
\\W是[^0-9a-zA-Z_]。非单词字符。
\\s是[\\t\\v\\n\\r\\f]。表示空白符,包括空格、水平制表符、垂直制表符、换行符、回车符、换页符。
\\S是[^\\t\\v\\n\\r\\f]。 非空白符。
.就是[^\\n\\r\\u2028\\u2029]。通配符,表示几乎任意字符。换行符、回车符、行分隔符和段分隔符除外。
//匹配所有的数字
let str = "1 2 3"
let reg = /\\d/g
console.log(str.match(reg))
//匹配所有的英文字母和下划线
let str = "a b c _"
let reg = /\\w/g
console.log(str.match(reg))
//匹配所有特殊符号(表示空白符,包括空格、水平制表符、垂直制表符、换行符、回车符、换页符)
let str = "a b c _"
let reg = /\\s/g
console.log(str.match(reg))
//通配符(表示几乎任意字符。换行符、回车符、行分隔符和段分隔符除外)
let str = "a b c _"
let reg = /./g
console.log(str.match(reg))
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
28
29
30
31
32
33
34
# 大法中🐱👤💨
// 数字匹配简写
// 取反
// \d就是[0 - 9]。表示是一位数字。💖
// \D就是[^ 0 - 9]。表示除数字外的任意字符。
var str = "s"
var reg = /\D/
console.log(reg.test(str));//true
var str = "g"
var reg = /\D/
console.log(reg.test(str));//true
var str = "H"
var reg = /\a/
console.log(reg.test(str));//false
var str = "j"
var reg = /\a/
console.log(reg.test(str));//false
// 表示数字、大小写字母和下划线。\w就是[0-9a-zA-Z_]💖
var str = "-"
var reg = /\w/
console.log(reg.test(str));//false
var str = "-j"
var reg = /\w/
console.log(reg.test(str));//true
var str = "1"
var reg = /\w/
console.log(reg.test(str));//true
var str = "_"
var reg = /\w/
console.log(reg.test(str));//true
//\s是[\t\v\n\r\f]。表示空白符,包括空格、水平制表符、垂直制表符、换行符、回车符、换页符。
// 大写S就取反
var str = "\n"
var reg = /\s/
console.log(reg.test(str));//true
var str = "$"
var reg = /\s/
console.log(reg.test(str));//false
var str = "$"
var reg = /\S/
console.log(reg.test(str));//true
// 通用
var str = "j"
var reg = /./
console.log(reg.test(str));//true
//无敌什么都能匹配
var str = "\n"
var reg = /[\w\w]/
console.log(reg.test(str));//false
var str = "^%"
var reg = /[\w\D]/
console.log(reg.test(str));//true
// 这种什么都匹配不了
var str = "$"
var reg = /[^\d\D]/
console.log(reg.test(str));//false
// 特殊用法💨
var str = "1"
var reg = /[\w\w]/ //匹配所有字符
console.log(reg.test(str));//true
var reg = /[^\w\w]/ //不匹配任何字符
console.log(reg.test(str));//false
//匹配a20 a30 a40
var str = "a10 a20 a30 a40 a50"
var reg = /a[2-4]0/g
console.log(reg.test(reg))//false
console.log(str.match(reg))//["a20", "a30", "a40"]
//匹配b c d
var str = "a b c d e"
var reg = /[b-d]/g
console.log(reg.test(reg))//true
console.log(str.match(reg))// ["b", "c", "d"]
//匹配所有的数字
var str = "1 2 3 4 5"
var reg = /[0-9]/g
console.log(reg.test(reg))//true
console.log(str.match(reg))//["1", "2", "3", "4", "5"]
//匹配所有的大小写英文字母
var str = "a b c d e A B C D"
var reg = /[A-Za-z]/g
console.log(reg.test(reg))//true
console.log(str.match(reg))//["a", "b", "c", "d", "e", "A", "B", "C", "D"]
//匹配 a - z
var str = "a - z"
var reg = /[a\\-z]/g //或 /[az-]/g 或 / [-az] / g
console.log(reg.test(reg))//true
console.log(str.match(reg))//["a", "z"]
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# 横向模糊匹配
横向模糊指的是,一个正则可匹配的字符串的长度不是固定的,可以是多种情况的。
//匹配abbc abbbc
let str = "abc abbc abbbc"
let reg = /ab{2,3}c/g
console.log(str.match(reg))
2
3
4
5
# 1、量词
量词也称重复。
{m,} 表示至少出现m次。
{m} 等价于{m,m},表示出现m次。
? 等价于{0,1},表示出现或者不出现。
+ 等价于{1,},表示出现至少一次。
* 等价于{0,},表示出现任意次,有可能不出现。
//匹配出现0次或1次
let str = "ac abc abbc abbbc"
let reg = /ab{0,1}c/g
let reg= /ab?c/g
console.log(str.match(reg)) //["ac", "abc"]
//匹配出现至少一次
let str = "ac abc abbc abbbc"
let reg = /ab{1,}c/g
let reg= /ab+c/g
console.log(str.match(reg)) //["abc", "abbc", "abbbc"]
//匹配出现任意次数
let str = "ac abc abbc abbbc"
let reg= /ab*c/g
console.log(str.match(reg)) // ["ac", "abc", "abbc", "abbbc"]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
练习中💨
var str = "heo helo hello helllo hellllo"
var reg = /hel{1,3}o/g
console.log(str.match(reg));//["helo", "hello", "helllo"]
var str = "heo helo hello helllo hellllo"
var reg = /hel{1,}o/g
console.log(str.match(reg));//["helo", "hello", "helllo", "hellllo"]
var str = "heo helo hello helllo hellllo"
var reg = /hel{2}o/g
console.log(str.match(reg));//["hello"]
//【?】0次或者1次
var str = "heo helo hello helllo hellllo"
var reg = /hel?o/g
console.log(str.match(reg));//["heo", "helo"]
//【+】至少出现了1次
var str = "heo helo hello helllo hellllo"
var reg = /hel+o/g
console.log(str.match(reg));//["helo", "hello", "helllo", "hellllo"]
//【*】任意次数
var str = "heo helo hello helllo hellllo"
var reg = /hel*o/g
console.log(str.match(reg));//["heo", "helo", "hello", "helllo", "hellllo"]
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
# 案例
1、匹配我们的手机号码(松散匹配) 1[3-9]后面9位数字
var str = "15866393005";
var reg = /^1[3-9]\d{9}$/
console.log(reg.test(str)); //true
2
3
用判断语句
var str = "15866393005";
var reg = /^1[3-9]\d{9}$/
var arr = reg.exec(str)
if (arr === null || arr === "") {
alert("没匹配!")
} else {
alert(arr[0]) //15866393005
}
2
3
4
5
6
7
8
2、qq邮箱
var str = "[email protected]"
var reg = /^[1-9][0-9]{4,10}@qq.com$/
console.log(reg.test(str));//true
2
3
3、24小时正则式
// 23:59
// 00:00
// 09
// 19
// 23
var str = "24:00"
var reg = /^[0-1][0-9]|[2][0-3]:[0-5][0-9]$/
console.log(reg.test(str));//false
var str = "00:00"
var reg = /^[0-1][0-9]|[2][0-3]:[0-5][0-9]$/
console.log(reg.test(str));//true
var str = "23:59"
var reg = /^[0-1][0-9]|[2][0-3]:[0-5][0-9]$/
console.log(reg.test(str));//true
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 2、贪婪匹配和惰性匹配
量词默认都是贪婪匹配的,即有多少个就匹配多少个,越多越好。
let str = "123 1234 12345 123456"
let reg = /\\d{2,5}/g
console.log(str.match(reg))//["123", "1234", "12345", "12345"]
2
3
而有时候我们可能需要的是惰性匹配,即尽可能少的匹配。
//其中/\\d{2,5}?/表示,虽然2到5次都行,当2个就够的时候,就不在往下尝试了。
let str= "123 1234 12345 123456";
let reg= /\\d{2,5}?/g;
console.log( str.match(reg) )//["12", "12", "34", "12", "34", "12", "34", "56"]
2
3
4
通过在量词后面加个问号就能实现惰性匹配,因此所有惰性匹配情形如下
{m,n}?
{m,}?
??
+?
*?
2
3
4
5
# 多选分支
一个模式可以实现横向和纵向模糊匹配。而多选分支可以支持多个子模式任选其一。
具体形式如下:(p1|p2|p3),其中p1、p2和p3是子模式,用|(管道符)分隔,表示其中任何之一。
let str = "hello world"
let reg = /hello|world/g
console.log(str.match(reg))//[hello,world]
2
3
但是多选分支默认是惰性的
let str = "good goodbye"
let reg = /good|goodbye/g
console.log(str.match(reg))//['good', 'good']
2
3
可以这么写
let str = "good goodbye"
let reg = /goodbye|good/g//把goodbye放前面就可以准确的获取到goodbye
console.log(str.match(reg))//['good', 'goodbye']
let str = "good goodbye"
let reg = /^good|goodbye$/g//^$是以什么为开头,什么味结束
console.log(str.match(reg))//['good', 'goodbye']
2
3
4
5
6
7
# 案例
1、匹配16进制颜色值
#ffbbad
#Fc01DF
#FFF
#ffE
var regex = /#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})/g;
var string = "#ffbbad #Fc01DF #FFF #ffE";
console.log( string.match(regex) );
// => ["#ffbbad", "#Fc01DF", "#FFF", "#ffE"]
2
3
4
5
6
7
8
9
10
11
12
2、匹配24小时制时间
23:59
02:07
var regex = /^([01][0-9]|[2][0-3]):[0-5][0-9]$/;
console.log( regex.test("23:59") );
console.log( regex.test("02:07") );
// => true
// => true
2
3
4
5
6
7
8
9
3、匹配日期,yyyy-mm-dd格式
var regex = /^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/;
console.log( regex.test("2017-06-10") );
// => true
2
3
# 二、正则表达式位置匹配
# 位置
位置指的是相邻字符之间的位置。
//可以把位置理解成每一个字符左右两边的空字符
let str = "hello"
let str = ""+"h"+"e"+"l"+"l"+"o"+""
2
3
4
# 位置匹配
# 1、锚字符,匹配位置的字符。
^ //(脱字符)匹配开头,在多行匹配中匹配行开头。
$ //(美元符号)匹配结尾,在多行匹配中匹配行结尾。
\\b //\\w和\\W之间的位置,也包括\\w和^之间的位置,也包括\\w和$之间的位置。
\\B //\\w与\\w、\\W与\\W、^与\\W,\\W与$之间的位置
(?=p) //正向先行断言。(?=p),其中p是一个子模式,即p前面的位置。
(?!p) //负向先行断言。(?!p),就是(?=p)的反面意思
(?<=p) //正向后行断言。(?<=p),即p后面的位置。
(?<!p) //负向后行断言。(?<!p),就是(?<=p)的反面意思
2
3
4
5
6
7
8
9
10
11
12
13
14
15
练习中💨
//【^】(脱字符)匹配开头,在多行匹配中匹配行开头。
var str = "hello heooo llo"
var reg = /^he/g
console.log(str.match(reg));//["he"]
var str = "hello heooo llo"
var reg = /he$/g
console.log(str.match(reg));//null
// 【$】(美元符号)匹配结尾,在多行匹配中匹配行结尾。
var str = "hello heooo llo"
var reg = /llo$/g
console.log(str.match(reg));//["llo"]
var str = "hello heooo llo"
var reg = /^llo/g
console.log(str.match(reg));//null
// 【\\b】 \\w和\\W之间的位置,也包括\\w和^之间的位置,也包括\\w和$之间的位置。
var str = "h e l l o"
var reg = /\b/g
console.log(str.replace(reg, "#"));//#h# #e# #l# #l# #o#
// 【\\B】 \\w与\\w、\\W与\\W、^与\\W,\\W与$之间的位置
var str = "hello"
var reg = /\B/g
console.log(str.replace(reg, "#"));//h#e#l#l#o
var str = "h e l l o"
var reg = /\B/g
console.log(str.replace(reg, "#"));//h e l l o
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
28
29
30
31
32
33
34
💨🐱👤
// 【(?= p)】 正向先行断言。(?=p),其中p是一个子模式,即p前面的位置。
var str1 = "hello"
var reg1 = /(?=l)/g
console.log(str1.replace(reg1, "#"));//he#l#lo
// 【(? !p)】 负向先行断言。(?!p),就是(?=p)的反面意思
var str2 = "hello"
var reg2 = /(?!l)/g
console.log(str2.replace(reg2, "#"));//#h#ell#o#
// 【(?<=p)】 正向后行断言。(?<=p),即p后面的位置。
var str3 = "hello"
var reg3 = /(?<=l)/g
console.log(str3.replace(reg3, "#"));//hel#l#o
// 【(?<!p)】 负向后行断言。(?<!p),就是(?<=p)的反面意思
var str4 = "hello"
var reg4 = /(?<!l)/g
console.log(str4.replace(reg4, "#"));//#h#e#llo#
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
案例
// 12345678 变成 12,345,678
var str = "12345678"
var reg = /(?!^)(?=(\d{3})+$)/g
console.log(str.replace(reg, ","));//12,345,678
2
3
4
相识-半
var str = "123456789"
var reg = /(?<=2)|(?<=5)/g
console.log(str.replace(reg, ","));//12,345,678
var str = "123456789"
var reg = /(?=3)|(?=6)/g
console.log(str.replace(reg, ","));//12,345,678
2
3
4
5
6
# 2、^和$
^(脱字符)匹配开头,在多行匹配中匹配行开头。
$(美元符号)匹配结尾,在多行匹配中匹配行结尾。
let str = "hello"
let reg = /^|$/g
console.log(str.replace(reg,"#"))//#hello#
2
3
要注意多行匹配模式时,二者是行的概念
let str = "i\\nlove\\njavascript"
let reg = /^|$/g
console.log(str.replace(reg,"#"))
// #i
// love
// javascript#
//需要加修饰符m
let str = "i\\nlove\\njavascript";
let reg = /^|$/gm;
console.log(str.replace(reg, "#"));
// #i#
// #love#
// #javascript#
2
3
4
5
6
7
8
9
10
11
12
13
14
# 3、\b和\B
\b是单词边界,具体就是\w和\W之间的位置,也包括\w和^之间的位置,也包括\w和$之间的位置。
let str = "[JS] Lesson_01.mp4";
let reg = /\\b/g;
console.log(str.replace(reg, "#"));//[#JS#] #Lesson_01#.#mp4#
2
3
\B就是\b的反面的意思,非单词边界。例如在字符串中所有位置中,扣掉\b,剩下的都是\B的。具体说来就是
\w与\w、\W与\W、^与\W,\W与$之间的位置。
let str = "[JS] Lesson_01.mp4";
let reg = /\\B/g;
console.log(str.replace(reg, "#"));//#[J#S]# L#e#s#s#o#n#_#0#1.m#p#4
2
3
# 4、先行断言和后行断言
先行断言和后行断言也被称为环视。
正向先行断言。
(?=p),其中p是一个子模式,即p前面的位置。
let str = "hello";
let reg = /(?=l)/g;
console.log(str.replace(reg, "#"));//he#l#lo
2
3
负向先行断言。
(?!p),就是(?=p)的反面意思
let str = "hello";
let reg = /(?!l)/g;
console.log(str.replace(reg, "#"));//#h#ell#o#
2
3
正向后行断言。
(?<=p),即p后面的位置。
let str = "hello";
let reg = /(?<=l)/g;
console.log(str.replace(reg, "#"));//hel#l#o
2
3
负向后行断言。
(?<!p),就是(?<=p)的反面意思
let str = "hello";
let reg = /(?<!l)/g;
console.log(str.replace(reg, "#"));//#h#e#llo#
2
3
# 案例
# 1、不匹配任何东西
let str = "hello";
let reg = /.^/g;
console.log(str.match(reg))//null
2
3
4
# 2、数字的千位分隔符表示法
把
"12345678",变成"12,345,678"。
let str = "123456789";
let reg = /(?!^)(?=(\\d{3})+$)/g;
console.log(str.replace(reg,","))//123,456,789
2
3
4
# 3、替换法
把
"12345678 123456789"替换成"12,345,678 123,456,789"
let str = "12345678 123456789";
let reg = /\\B(?=(\\d{3})+\\b)/g;
console.log(str.replace(reg,","))//12,345,678 123,456,789
2
3
4
# 4、验证密码
密码长度
6-12位,由数字、小写字符和大写字母组成,但必须至少包括2种字符。
- 同时包含数字和小写字母
- 同时包含数字和大写字母
- 同时包含小写字母和大写字母
- 同时包含数字、小写字母和大写字母
let str = "123abcdef112";
let reg = /((?=.*\\d)(?=.*[a-z])|(?=.*\\d)(?=.*[A-Z])|(?=.*[A-Z])(?=.*[a-z]))^[0-9A-Za-z]{6,12}$/g;
console.log(reg.test(str))//true
2
3
4
另外一种解法
- 不能是纯数字
- 不能是纯小写
- 不能是纯大写
let str = "AAAAAA";
let reg = /(?!^\\d{6,12}$)(?!^[a-z]{6,12}$)(?!^[A-Z]{6,12}$)^[0-9A-Za-z]{6,12}$/;
console.log(reg.test(str))//false
2
3
4
# 三、正则表达式括号作用
# 分组和分支结构
# 一、分组和分支结构
分组
var regex = /(ab)+/g;
var string = "ababa abbb ababab";
console.log( string.match(regex) );
// => ["abab", "ab", "ababab"]
2
3
4
分支结构
var regex = /^I love (JavaScript|Regular Expression)$/;
console.log( regex.test("I love JavaScript") );
console.log( regex.test("I love Regular Expression") );
// => true
// => true
2
3
4
5
# 二、引用分组
这是括号一个重要的作用,有了它,我们就可以进行数据提取,以及更强大的替换操作。
提取数据
let str = "2021-10-06";
let reg = /(\\d{4})-(\\d{2})-(\\d{2})/;
console.log(reg.test(str))//任意的正则操作,以下都可以
// console.log(reg.exec(str))
// console.log(str.match(reg))
//通过构造函数的全局属性$1至$9来获取
console.log(RegExp.$1)//2021
console.log(RegExp.$2)//2021
console.log(RegExp.$3)//2021
2
3
4
5
6
7
8
9
10
替换数据
let str = "2021-10-06";
let reg = /(\\d{4})-(\\d{2})-(\\d{2})/;
console.log(str.replace(reg,"$2/$3/$1"))//10/06/2021
//等价于
let str = "2021-10-06";
let reg = /(\\d{4})-(\\d{2})-(\\d{2})/;
console.log(str.replace(reg,()=>{
return RegExp.$2 + "/" + RegExp.$3 + "/" + RegExp.$1
}))
2
3
4
5
6
7
8
9
10
11
12
# 三、反向引用
除了使用相应API来引用分组,也可以在正则本身里引用分组。但只能引用之前出现的分组,即反向引用。
//\\1的意思是引用前面的(-|\\/|\\.)分组
let reg = /\\d{4}(-|\\/|\\.)\\d{2}\\1\\d{2}/;
let str1 = "2021-10-06";
let str2 = "2021/10/06";
let str3 = "2021.10.06";
let str4 = "2021-10/06";
console.log(reg.test(str1))//true
console.log(reg.test(str2))//true
console.log(reg.test(str3))//true
console.log(reg.test(str4))//false
2
3
4
5
6
7
8
9
10
# 1、括号嵌套的时候,以左括号为准
let reg = /^((\\d)(\\d(\\d)))\\1\\2\\3\\4$/;
let str1 = "1231231233";
console.log(reg.test(str1))//true
console.log(RegExp.$1)//123
console.log(RegExp.$2)//1
console.log(RegExp.$3)//23
console.log(RegExp.$4)//3
2
3
4
5
6
7
# 2、\10表示什么呢
\10是表示第10个分组,不是表示\1和0
var regex = /(1)(2)(3)(4)(5)(6)(7)(8)(9)(#) \\10+/;
var string = "123456789# ######"
console.log( regex.test(string) );
// => true
2
3
4
# 3、引用不存在的分组
因为反向引用,是引用前面的分组,但我们在正则里引用了不存在的分组时,此时正则不会报错,只是匹配反向引用的字符本身。
var regex = /\\1\\2\\3\\4\\5\\6\\7\\8\\9/;
console.log( regex.test("\\1\\2\\3\\4\\5\\6\\7\\8\\9") );
console.log( "\\1\\2\\3\\4\\5\\6\\7\\8\\9".split("") );
2
3
# 四、非捕获分组
如果只想要括号最原始的功能,但不会引用它,即,既不在API里引用,也不在正则里反向引用。此时可以使用非捕获分组(?:p)。
var regex = /(?:ab)+/g;
var string = "ababa abbb ababab";
console.log( string.match(regex) );
// => ["abab", "ab", "ababab"]
2
3
4