正则详解

什么是正则

正则就是一个规则,用来处理 字符串 的规则

1、正则匹配

编写一个规则,验证某个字符串是否符合这个规则,正则匹配使用的是 test 方法

2、正则捕获

编写一个规则,在一个字符串中把符合规则的内容都获取到,正则捕获使用的方法:正则的 exec 方法、字符串中的 splitreplacematch 等方法都支持正则

1
2
var reg = /^$/;
// 两个斜杠中间包含一些内容就是正则,两个斜杠之间包含的全部内容都是元字符

正则的元字符和修饰符

任何一个正则都是由 元字符修饰符 组成的

修饰符

g (global):全局匹配

i (ignoreCase):忽略大小写匹配

m (multiline):多行匹配

元字符

【 量词元字符 】

+:让前面的元字符出现一次到多次

?:出现零到一次

*:出现零到多次

{n}:出现 n 次

{n,}:出现 n 到多次

{n,m}:出现 n 到 m 次

【 特殊意义的元字符 】

\:转义字符(把一个普通字符转变为有特殊意义的字符,或者把一个有意义字符转换为普通的字符)

.:出了 \n (换行符) 以外的任意字符

\d:匹配一个 0~9 之间的数字

\D:匹配任意一个 非0~9 之间的数字(大写字母和小写字母的组合正好是反向的)

\w:匹配一个 0~9或字母或_ 之间的字符

\s:匹配一个任意空白字符

\b:匹配一个边界符

x|y:匹配 x 或者 y 中的一个

[a-z]:匹配 a-z 中的任意一个字符

[^a-z]:和上面的相反,匹配任意一个 非a-z 的字符

[xyz]:匹配 x 或者 y 或者 z 中的一个字符

[^xyz]:匹配除了 xyz 以外的任意字符

():正则的小分组,匹配一个小分组(小分组可以理解为大正则中的一个小正则)

^:以某一个元字符开始

$:以某一个元字符结束

?::只匹配不捕获

?=:正向预查

?!:负向预查

……

除了以上特殊元字符和量词元字 符,其余的都叫做普通元字符:代表本身意义的元字符

参考:RegExp

元字符详解

^ $

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* 匹配一个到多个数字 */
var reg = /\d+/; // 包含 xxx 即可, 这里说明包含1到多个数字即可
var str = '新年2018快乐2019';
reg.test(str); // true

/* 匹配以一个到多个数字开始 */
reg = /^\d+/;
reg.test(str); // false

/* 匹配以一个到多个数字开始结束并且中间也是数字 */
reg = /^\d+$/; // 只能是 xxx 的,这里说明只能是1到多个数字
reg.test('2018'); // ture
reg.test('2018新年快乐2019'); // false
reg.test('2'); // true ^ 或者 $ 只是一个修饰符或者声明,不会占据字符串的位置

\

1
2
3
4
5
6
7
8
9
var reg = /^2.3$/;
reg.test('2.3'); // true
reg.test('2+3'); // true
// 点在正则中的意思是 匹配除了 \n 以外的任意字符,而不是单纯的小数点

reg = /^2\.3$/;
reg.test('2.3'); // true
reg.test('2+3'); // false
// 使用转义字符把点转换为小数点本身的意思

x|y

1
2
3
4
5
6
7
8
9
10
11
var reg = /^18|19$/;
// 符合这个规则的有很多, 例如:18 19 189 119 819 181 1819……
/*
表示的意思有:
1. 18或者19
2. 以1开头 以9结尾 中间是8或者1
3. 以18开头或者以19结尾即可
*/

var reg = /^(18|19)$/;
// 此时只有18或者19符合规则

():正则中的分组,也可以理解为一个大正则中的一个正则(包起来的部分是一个整体);在正则中我们可以使用小括号 改变一些默认的优先级

小分组还有第二个作用: 分组引用

小分组的第三个作用:分组捕获

1
2
3
4
5
6
/*
分组引用:
\1 或者 \2 …… 出现和第N个分组一模一样的内容
*/
var reg = /^([a-z])([a-z])\2([a-z])$/;
// 符合这个规则的字符串包括:book、week、attr、http……

[]

[xyz]、【^xyz】、[a-z]、【^a-z】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//	\w:数字字母下划线中的任意一个字符
var reg = /^[a-zA-Z0-9_]$/; // 等价于 \w

/* 中括号中出现的元字符,一般都代表本身的含义 */
var reg = /^[.?+&]+$/;
// 里面的四个元字符都是本身的含义,例如:点就是小数点,不是所谓的任意字符……

// 需求:匹配样式类名的规则 (数字、字母、下划线、-),并且不能以 - 开头
// var reg = /^[\w-]+$/;
// var reg = /^[0-9a-zA-Z_-]+$/; // 这两个没有处理以-开头的情况
var reg = /^\w[\w-]*$/;


// 需求:验证 18~65 之间的年龄
// var reg = /^[18-65]$/; // 这种做法是错的
// 表示的意思是 1或者8~6或者5中的任意一个字符,中括号中出现的18不是数字18,而是1或者8,并且当前正则是非法的,因为不能设置 8~6 这种范围
/*
正确的应该分三个阶段处理:
18 或者 19 /(18|19)/
20~59 /(2-5)\d/
60~65 /(6[0-5])/
*/
var reg = /^((18|19)|([2-5]\d)|(6[0-5]))$/;

常用的正则表达式编写

验证是否为有效数字

1
2
3
4
5
6
7
8
/*
可能是正数,也可能是负数
可能是整数或者小数 (假如是小数,只要出现小数点,小数点前面必须有数字,后面至少要跟一位数字)
*/
var reg = /^-?(\d|([1-9]\d+))(\.\d+)?$/;
// -? 部分表示:负号可有可无
// (\d|([1-9]\d+)) 部分表示:\d 一位数可以使任何值;([1-9]\d+) 多位数不能以零开头
// (\.\d+)? 部分表示:小数部分可有可无,有的话点后面必须份上一位数字

验证手机号码

1
2
3
//	11 位数字, 以 1 开头
var reg = /^1\d{10}$/;
// 验证手机号码是将手机号码发送到服务器,由服务器调用第三方发送手机验证码平台

匹配用户名:真实姓名

1
2
3
4
5
//	/^[\u4E00-\u9FA5]$/;	匹配中文汉字的正则
var reg = /^[\u4E00-\u9FA5]{2,5}$/;

// 可以匹配艺名的正则,例如:尼古拉斯·赵四……
var reg = /^[\u4E00-\u9FA5]{2,10}(·[\u4E00-\u9FA5]{2,10})?$/;

匹配邮箱

1
2
3
4
5
6
7
8
9
10
var reg = /^\w+((-\w+)|(\.\w+))*@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
// \w+
// ((-\w+)|(\.\w+))*
// [A-Za-z0-9]+
// ((\.|-)[A-Za-z0-9]+)*
// \.[A-Za-z0-9]+
/*
以数字字母下划线开头;@前面可以是 数字、字母、下划线、-、. 这些符号;-和. 不能连续出现,出现一次后面必须份上数字字母下划线
@后面的部分支持 企业邮箱;.com.cn 多域名情况 等。
*/

匹配身份证号码

1
2
3
4
5
6
7
8
9
/*
身份证号码规则:
18位; 前17位必须是数字; 最后一位可以是数字或者X(X代表数字10);
前6位表示 省市县; 接下来的八位表示出生年月日; 倒数第二位数字代表 奇男偶女
*/
var reg = /^(\d{6})(\d{4})(\d{2})(\d{2})\d{2}(\d)(\d|X)$/;
// 这样使用小分组的写法不仅可以匹配,而且以后在捕获的时候,不仅可以把大正则匹配的结果捕获到,里面每一个小分组(小正则)匹配的结果也可以单独的捕获到 “分组捕获”
// 出生年月日这块如果有其他需求(比如只能是 1950-201x年的)应该这样写
// /^((19[5-9]\d)|(20((0\d)|(1[0-x]))))$/

正则捕获

把当前字符串中符合正则的字符捕获到

RegExp.prototype: exev 实现正则捕获的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var str = '新年快乐2018猪事顺利2019';
var reg = /\d+/;

reg.exec(str);

/*
* 当正则捕获的时候:
* 1、先去验证当前字符串和正则是否匹配,如果不匹配返回的结果是 null (没有捕获到任何的内容)
* 2、如果匹配,从字符串最左边开始,向右查找到匹配的内容,并且把匹配到的内容返回
*
* exec 捕获到结果的格式:
* 获取的结果是一个数组
* 数组中的第一项是当前本次大正则在字符串中匹配到的结果
* index:记录了当前本次捕获到结果的起始索引
* input:当前正则操作的原始字符串
* 如果当前正则中有分组,获取的数组中,从第二项开始都是每个小分组本次匹配到的结果 (通过 exec 可以把分组中的内容捕获到)
*
* 执行一次 exec 只能把符合正则规则条件中的一个内容捕获到,如果还有其他符合规则的,需要再次执行 exec 才有可能捕获到。
*/

正则捕获结果

正则捕获存在懒惰性

执行一次 exec 捕获到第一个符合规则的内容,第二次执行 exec ,捕获到的依然是第一个匹配的内容,后面匹配的内容不管执行多少次 exec 都无法捕获到

解决正则捕获的懒惰性:在正则的末尾加修饰符 g (表示全局匹配)

1
2
3
4
5
6
7
8
9
10
11
12
//	正则为什么会存在懒惰性?
/*
* 正则本身有一个 `lastIndex` 属性 (下一次正则在字符串中匹配查找的开始索引)
* 默认值是 0,从字符串第一个字符开始查找匹配的内容
* 默认不管指定多少遍 exec 方法,正则的 `lastIndex` 值都不会变 (也就是第二次以后查找的时候还是从第一个字符找,所以找到的结果永远都是第一个匹配的内容)
* 而且当我们手动把 `lastIndex` 进行修改的时候,不会起到任何的作用
*/

// 为什么加修饰符 g 就解决了懒惰性?
/*
* 加了修饰符 g,每一次 exec 结束后,浏览器默认会把 `lastIndex` 值进行修改,下一次从上一次结束从位置开始查找,所以可以得到后面匹配的内容了
*/

正则捕获懒惰性

exec 有自己的局限性:执行一次 exec 只能捕获到一个和正则匹配的结果(即使加了修饰符g),如果需要都捕获到,我们需要执行 N 次 exec 方法才可以

我们可以封装一个 myExecAll 方法,执行一次这个方法,可以把当前正则匹配到的全部内容都捕获到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
RegExp.prototype.myExecAll = function myExecAll () {
// this 指当前需要处理的正则
// str 指当前需要处理的字符串
var str = arguments[0] || '',
result = [];
// 首先应该判断 this 是否加了全局修饰符 g,如果没有加,为了防止下面执行出现死循环,我们只让其执行一次 exec 即可,把执行一次的结果直接返回
if (!this.global) {
return this.exec(str);
}
var ary = this.exec(str);
while(ary) {
result.push(ary[0]);
ary = this.exec(str);
}
return result;
};

// var reg = /\d+/;
var reg = /\d+/g;
reg.myExecAll('新2018年2019快2020乐2021');

使用字符串 match 方法实现捕获

1
2
3
var reg = /\d+/g;
var str = '新2018年2019快2020乐2021';
str.match(reg); // ["2018","2019","2020","2021"]

使用字符串 match 捕获:

1、如果正则加了修饰符 g,执行一次 match 会把所有正则匹配的内容捕获到

2、如果没有加修饰符 g,执行一次 match 只能把第一个匹配的结果捕获到

局限性:在加了修饰符 g 的情况下,执行 match 方法只能把大正则匹配到的内容捕获到,对于小分组捕获的内容方法给其自动忽略了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//	需求: 把 {n} 整体捕获到,而且还要把括号中的数字也获取到
var str = 'my name is {0}, i am {1} years old, 2019';
var reg = /\{(\d+)\}/g;

// str.match(reg); // ["{0}", "{1}"]
// 想要获取小分组中的内容,我们只能使用 exec 方法处理了
// reg.exec(str); // 多次执行
function fn(reg,str) {
var ary = reg.exec(str),
result = [];
while(ary) {
result.push(ary);
ary = reg.exec(str);
}
return result;
}

使用 test 方法实现正则捕获

不管是正则的匹配还是正则的捕获,在处理时候的原理是没有区别的:从字符串的第一个字符向后查找,找到符合正则规则的字符,如果可以找到,说明正则和字符串匹配( test 检测返回 true;exec 捕获返回捕获的内容),如果找到末尾都没有匹配的,说明正则和字符串不匹配 ( test 检测返回 false;exec 捕获返回 null)

如果正则设置了修饰符 g,不管使用 test 还是 exec 中的任何方法,都会修改 lastIndex 值(下一次查找是基于上一次匹配结果的末尾开始查找的)

1
2
3
4
5
6
7
var reg = /\{(\d+)\}/g;
var str = 'my name is {0}~~'
if (reg.test(str)) {
console.log(reg.lastIndex); // 14
// 此时 lastIndex 值已经被修改,再使用 exec 方法已经匹配不到内容了
console.log(reg.exec(str)); // null
}

使用 test 不仅可以找到匹配的内容,也能像 exec 一样把找到的内容获取到

test 返回的结果是 true/false,所以靠返回结果肯定不行

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
/* test 实现捕获 */
var reg = /\{(\d+)\}/g;
var str = 'my name is {0}~~, i am {1} years old~~';
reg.test(str); // true
RegExp.$1; // 0 获取到当前本次匹配内容中第一个小分组捕获的内容

reg.test(str); // true
RegExp.$1; // 1 test 可以实现捕获,但是每一次只能获取到当前本次匹配结果中第 N 个分组捕获的内容;$1第一个分组 $2第二个分组 ……

/* 使用 test 方法和使用 exec 方法实现全部捕获的对比
// test 方法实现捕获
var result = [];
while (reg.test(str)) {
result.push(RegExp.$1);
}
console.log(result); // ["0","1"]

// exec 方法实现捕获
var result = [],
ary = reg.exec(str);
while (ary) {
result.push(ary[1]);
ary = reg.exec(str);
}
console.log(result); // ["0","1"]
*/

正则只匹配不捕获的处理

字符串中常用的支持正则的方法:matchsplitreplace ……

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var str = 'name=张三&age=20&lx=student';
str.split(/&|=/); // ["name", "张三", "age", "20", "lx", "student"]

str.split(/(&|=)/); // ["name", "=", "张三", "&", "age", "=", "20", "&", "lx", "=", "student"]

/* 在使用 split 进行字符串拆分的时候,如果正则中包含小分组,会把小分组中的内容都捕获到,放在最后的数组中 */
// 本案例中的小括号仅仅是为了实现 改变默认的优先级 问题,但是我们不想把分组中的内容捕获到 => 只想匹配不想捕获 我们可以使用( ?: )
// str.split(/(?:&|=)/);

str.split(/(?:&|=)/); // ["name", "张三", "age", "20", "lx", "student"]

/* 只匹配不捕获 */
// 在当前一个分组中加了 ?: ,在正则检测匹配的时候,小分组可以起到自己应有的作用(例如:改变优先级……),但是在捕获的时候,遇到带 ?: 的小分组,浏览器不会把当前这个分组中匹配的内容单独去捕获了

var reg = /^(\d{6})(\d{4})(\d{2})(\d{2})(\d{2})(\d)(\d|X)$/;
reg.exec('123456789123456789'); // ["123456789123456789", "123456", "7891", "23", "45", "67", "8", "9", ……]

var reg = /^(\d{6})(\d{4})(\d{2})(\d{2})(?:\d{2})(\d)(?:\d|X)$/;
reg.exec('123456789123456789'); // ["123456789123456789", "123456", "7891", "23", "45", "8", ……]


var reg = /^-?(\d|([1-9]\d+))(\.\d+)?$/;
// 计算是第几个分组的时候,从左向右找 ( 即可;在这个例子中:(\d|([1-9]\d+)) 是第一个小分组;([1-9]\d+) 是第二个小分组;(\.\d+) 是第三个小分组。

replace 实现正则捕获的原理

replace:字符串中原有字符的替换

str.replace(old,new)

1
2
3
4
5
6
var str = '新年快乐2018新年快乐2019';
str = str.replace('新年快乐','新年快乐猪事顺心');
str = str.replace('新年快乐','新年快乐猪事顺心');
// "新年快乐猪事顺心猪事顺心2018新年快乐2019" 没有实现我们希望的效果

// 在不使用正则的情况下,执行一次 replace 只能替换一个原有字符,第二次执行 replace,还是从字符串的开始位置查找,把最新找到的字符替换为新字符(类似于正则捕获时候的懒惰性:每一次执行都是从字符串最开始的位置查找)

replace 一般都是和正则搭配在一起使用的

1
2
3
var str = '新年快乐2018新年快乐2019';
str = str.replace(/新年快乐/g,'新年快乐猪事顺心');
// "新年快乐猪事顺心2018新年快乐猪事顺心2019"

replace 原理:

1、当 replace 方法执行,第一项传递一个正则

正则不加 g:把当前字符串中第一个和正则匹配的结果捕获到,替换成新的字符

正则加 g:把当前字符串中所有和正则匹配的内容都分别捕获到,而且每一次捕获,都会把当前捕获的内容替换为新字符

2、当 replace 方法执行,第二个参数传递的是一个函数(回调函数)

首先用正则在字符串中进行查找匹配,匹配到一个符合规则的,就把传递的函数执行一次

不仅执行这个函数,而且还把正则本次捕获的结果(和执行 exec 捕获的结果一样:数组、大正则匹配、小分组匹配 都有) 当做实参传递给这个函数(这样就可以在函数中获取这些值:而这些值就是正则每一次捕获的结果)

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
var str = 'my name is {0},i am {1} years old,i can {2}!';
var reg = /\{(\d+)\}/g;
str.replace(reg, function(){
// 传递的函数一共被执行三次
// console.log(arguments) 每一次匹配捕获到结果,不仅把这个方法执行了,而且还会把当前捕获的结果当做实参传递给这个函数(arg)
/*
第一次执行函数,获取的是 arg 类数组
0:'{0}' 本次大正则匹配的结果
1:'0' 本次第一个小分组匹配的结果
2:11 本次大正则匹配结果在字符串中的索引 index
3:'my name ……' 原始字符串 input

和每一次执行 exec 实现捕获的结果非常类似
*/


// return XXX; // 每一次执行函数,函数中 return 的结果,都相当于把本次大正则匹配的内容替换掉(原始字符串不变)
})

// 例如:
var str = '新年快乐2018新年快乐2019';
str = str.replace(/新年快乐/g,function(){
return "新年快乐猪事顺心"
});
console.log(str); // "新年快乐猪事顺心2018新年快乐猪事顺心2019"

单词首字母大写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* 单词首字母大写 */
var str = 'an old gentleman whose-eyesight-was failing came to stay in a hotel room with a bottle of wine in each hand.';
// var reg = /\b\w+\b/g/;
// \b 代表的是边界:单词左右两边是边界,-的左右两边也是边界,所以这里会把 'whose-eyesight-was'算作是三个单词(我们想把它当做一个)

// 1、先把混淆边界符的中杠替换为下划线
str = str.replace(/-/g, '_');
// 2、通过边界符匹配到每一个单词
str = str.replace(/\b(\w)(\w*)\b/g, function(){
return arguments[1].toUpperCase() + arguments[2];
})
// 3、再把之前替换的下划线重新赋值为中杠
str = str.replace(/_/g, '-');
console.log(str);

时间字符串格式化

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
var str = '2019-01-01 13:28:32';
// "2019年01月01日 13时28分32秒"

/* 方法一:通过 - : 逐步分割替换达到格式化的目的 */
/* 方法二:通过转变为标准日期对象来修改;Date(), getFullYear()…… */

/* 方法三:使用正则实现 */
// 1、执行一次捕获操作,得到需要的六个结果
var reg = /^(\d{4})-(\d{1,2})-(\d{1,2})\s+(\d{1,2}):(\d{1,2}):(\d{1,2})$/g;
str = str.replace(reg, function(){
var arg = arguments;
return `${arg[1]}${arg[2]}${arg[3]}${arg[4]}${arg[5]}${arg[6]}秒`;
});
// str = str.replace(reg, '$1年$2月$3日 $4时$5分$6秒') // $1 等价于第一个分组中获取的内容,类似于上面代码的 arg[1];
console.log(str); // "2019年01月01日 13时28分32秒"

// 使用 match 方法实现
var str = '2019-01-01 13:28:32';
var reg = /\d+/g,
ary = str.match(reg); // ["2019", "01", "01", "13", "28", "32"]
// str = `${ary[0]}年${ary[1]}月${ary[2]}日 ${ary[3]}时${ary[4]}分${ary[5]}秒`;
var template = '{0}年{1}月{2}日 {3}时{4}分{5}秒';
// {0} ==> ary[0] ==> 2019 {1} ==> ary[1] ==> 01 ……
// 我们首先获取模板中的 {0} (同时获取数字n),把数字 n 作为 ary 的索引,获取到需要的日期数据,把获取的日期数据整体替换 {n} 即可
template = template.replace(/\{(\d+)\}/g, function(){
var index = arguments[1],
value = ary[index];
return value;
});
console.log(template);


/* 通过这个思想我们可以封装一个 myFormatTime() 方法来格式化时间字符串 */
String.prototype.myFormatTime = function myFormatTime() {
var ary = this.match(/\d+/g),
template = arguments[0] || '{0}年{1}月{2}日 {3}时{4}分{5}秒'; // 如果传递自己的格式模板,就按传递的来解析,否则按照默认的模板解析
template = template.replace(/\{(\d+)\}/g, function(){
var value = ary[arguments[1]] || '0';
value.length < 2 ? value = '0' + value : null;
return value;
});
return template;
};

var str = '2019-01-01';
str = str.myFormatTime(); // "2019年01月01日 00时00分00秒"

// 可以根据自己设置的模板来解析,更加灵活
str = str.myFormatTime('{1}-{2} {3}:{4}'); // "01-01 00:00"
var str = '2019-01-01 13:28:32';
str = str.myFormatTime('{3}:{4}:{5}'); // "13:28:32"

去除字符串首尾空格

1
2
3
4
5
6
7
8
9
10
11
12
13
var str = '  去除首位空格, 去除末尾空格  '
// str.trim() // "去除首位空格, 去除末尾空格"
// str.trimLeft() // "去除首位空格, 去除末尾空格 "
// str.trimRight() // " 去除首位空格, 去除末尾空格"

// 使用 trim() 方法浏览器有兼容性问题,可以使用正则来处理
str = str.replace(/^\s+|\s+$/g, '');

// 可以将这个方法封装起来
String.prototype.myTrim = function myTrim() {
return this.replace(/^\s+|\s+$/g, '');
};
console.log(str.myTrim()); // "去除首位空格, 去除末尾空格"

URL地址栏问号传参值的解析

1
2
3
4
5
6
7
8
9
10
11
12
13
String.prototype.myQueryURLParameter = function myQueryURLParameter (){
var obj = {};
this.replace(/([^?&=#]+)=([^?&=#]+)/g, function () {
obj[arguments[1]] = arguments[2];
});
this.replace(/#([^?=&#]+)/g, function () {
obj['HASH'] = arguments[1];
});
return obj;
};

var url = 'https://www.baidu.com/?name=zhangsna&age=20&sex=0#student';
url.myQueryURLParameter(); // {name: "zhangsna", age: "20", sex: "0", HASH: "student"}

创建正则两种方式的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//	字面量方式
var reg = /\d+/img;

// 构造函数创建
// new RegExp('[元字符]','[修饰符]')
var reg2 = new RegExp('\\d+', 'img');
// 使用构造函数创建和字面量方式创建,最主要的区别是:构造函数创建,用到转义字符需要写 “\\” 才可以

// 使用构造函数方式写出验证是否为有效数字的正则
var reg = new RegExp('^-?(\\d|([1-9]\\d+))(\\.\\d+)?$');


/* 既然构造函数方法不方便使用,那为什么还要使用呢? 来看看下面这个需求: */
// 我们想在正则中动态加入一个变量的值,作为正则的一部分
var strClass = 'String';
// var reg = /^\[object '+strClass+'\]$/; // 字面量方式中出现的所有字符都叫做元字符,例如:在当前案例中 '+ 不是字符串拼接,属于让单引号出现一到多次……
// 这样的需求就只能通过构造函数的方式来做了
// var reg = new RegExp('^\\object '+ strClass + '\\]$');
reg = new RegExp(`^\\[object ${strClass}\\]$`);
console.log(reg.toString());
打赏功能
-------------本文结束感谢您的阅读-------------
0%