正则
1.var stuList = document.getElementById('stuList'),
2. stuBody = stuList.tBodies[0],
3. stuRows = stuBody.rows;
4.//->开始的时候页面中没有TR,所以stuRows是一个空的类数组
5.
6.~function () {
7. //->GET DATA
8. ...
9.
10. //->BIND DATA
11. var str = ``;
12. ...
13. stuBody.innerHTML = str; //->向页面中增加了20个TR
14.
15. console.log(stuRows); //->页面中TBODY结构中的内容改变了,根据DOM的映射机制,此处不需要重新的获取,stuRows中存储的就是最新的20条数据
16.}();
正则
用来处理
字符串
的规则
验证当前的字符串是否符合规则
–匹配
把字符串中符合规则的字符捕获到
–捕获
正则匹配:
[正则].test([字符串])
正则捕获:[正则].exec([字符串])
或者[字符串].match([正则])
或者[字符串].replace([正则],function...)
或者[字符串].split([正则])
…
元字符和修饰符
一个正则就是由元字符和修饰符组成的,想要学会编写自己所需的规则,需要牢牢掌握元字符和修饰符
修饰符
- i(ignoreCase):忽略单词大小写匹配
- m(multiline):多行匹配
- g(global):全局匹配
1.//->修饰符放在最后一个斜杠的后面
2.var reg = /^\d+$/img;
3.
4.//->实例创建方式中,修饰符放在第二个实参字符串中
5.var reg = new RegExp('','img');
特殊元字符
- \:转义字符,把普通元字符转换为特殊的意义或者把特殊元字符转换为普通的意义,例如:
/\d/ d本身是一个字母,前面加一个转义字符,代表0~9之间的一个数字
或者/\./ 点在正则中代表任意字符(特殊含义),此处加上转义字符,代表的就是本身意思点了
- ^:以某一个元字符开始,例如:
/^1/ 代表当前的字符串应该是以1开始的
- $:以某一个元字符结束,例如:
/2$/ 代表当前字符串最后一个字符应该是以2结尾
- \d:代表一个0~9之间的数字
- \D:和\d正好相反,代表一个非0~9之间的任意字符(大写字母都和小写字母的是相反的)
- \w:数字、字母、下划线 三者中的任意一个
- \n:匹配一个换行符
- \b:匹配一个边界
- \s:匹配一个空白字符
- .:除了\n以外的任意一个字符
- x|y:x或者y中的一个字符
- ():分组
- [a-z]:匹配一个a-z中的任意字符
/[0-9]/ 0~9之间的任何一个数字,等价于\d
- [^a-z]:除了a-z以外的任意一个字符,这里^是取反的意思
- [xyz]:x或者y或者z,三者中的一个
- [^xyz]:除了三者以外的任意一个字符
- ?=:正向预查
- ?!:负向预查
- ?: :只匹配不捕获
量词元字符
- * :前面的元字符出现零次到多次
- + :前面的元字符出现一次到多次
- ? :前面的元字符出现零次或者一次
- {n}:出现n次
- {n,}:出现n到多次
- {n,m}:出现n到m次
1.//->两个斜杠中间包起来的都是正则的元字符
2.//1、特殊元字符:有特殊含义的
3.//2、量词元字符:代表出现多少次
4.//3、普通元字符:代表本身含义的
5.var reg = /^\d+$/g;
6.var reg = new RegExp('[元字符]','[修饰符]');
常用的正则表达式
中括号的一些细节问题
1.//->中括号里面出现的多位数字,不是多位数,而是数字中出现的任意一个
2.var reg = /^[18]$/; //->1或者8中的一个数字
3.var reg = /^[16-85]$/; //->1或者6-8或者5,三者中的一个数字
4.
5.//->\w使用中括号的方式表达:数字、字母、下划线
6.var reg = /^[0-9a-zA-Z_]$/;
7.
8.//->中括号中出现的元字符一般都是自己本身的意思(即时具备特殊的意思,很多元字符也都自动变为本身的意思了)
9.var reg = /^[+-.\d?]$/; //->除了\d依然代表的是0~9中的一个数字,其余的都是代表本身的意思
小括号分组的一些作用和细节
1./*
2. * var reg = /^18|19$/;
3. * //->按照我们本身的理解,应该是18或者19两个中的任意一个,符合x|y这个元字符的规则
4. * //->但是现实不是这样的,上面的规则,18/19/181/189/119/819...都符合,它识别和处理的规则特别乱
5. * var reg = /^(18|19)$/; //->当我们使用分组把它包起来的时候就好了,现在只能匹配18或者19了,其余的都不可以
6.*/
7.=>正则中分组`()`的第一个作用:改变默认的优先级
8.
9.=>分组的第二个作用是:分组引用
10.//->\1 或者 \2 或者 \数字
11.//代表个对应分组出现一模一样的内容,也就是\1代表和第一个分组出现的内容一模一样
12.var reg = /^([a-z])([a-z])\2\1$/;
13.//->oppo moom noon toot ...
14.
15.=>分组的第三个作用:分组捕获
1./*
2. * 1、手机号码(简单)
3. * ->以1开头
4. * ->11位数字
5.*/
6.var reg = /^1\d{10}$/;//->同时加了^和$,次正则可以理解为只能是某某某规则;如果两个都不加,只要字符串中有一部分符合这个规则即可
7.
8./*
9. * 2、验证年龄:18~65
10. * -> 18或者19
11. * -> 20~59
12. * -> 60~65
13. * 分三个阶段完成操作
14. */
15.var reg = /^((18|19)|([2-5]\d)|(6[0-5]))$/;
16.
17./*
18. * 3、验证中文姓名的
19. * -> 只能是中文汉字
20. * 第一个汉字的ASCII码:\u4E00
21. * 最后一个汉字ASCII码:\u9FA5
22. * -> 正常一般都是2~4位
23. */
24.var reg = /^[\u4E00-\u9FA5]{2,4}$/;
25.reg = /^[\u4E00-\u9FA5]{2,5}(·[\u4E00-\u9FA5]{2,5})?$/; //->支持:大卫·贝克汉姆 这种英文译名
26.
27./*
28. * 4、验证是否为有效数字的
29. * -> 可能出现-,也可能不出现
30. * -> 一位数可以是零,多位数零不能作为开头
31. * -> 小数部分可能有可能没有,如果一但有,小数点后面必须有数字
32. */
33.var reg = /^-?(\d|([1-9]\d+))(\.\d+)?$/;
34.
35./*
36. * 5、验证身份证号码
37. * -> 简单:前17位是数字,最后一位数字或者X
38. * -> 完善:我们需要在身份证中获取到 省市县、出生年月日、性别 等信息
39. */
40.//var reg = /^\d{17}(\d|X)$/;
41.var reg = /^(\d{6})(\d{4})(\d{2})(\d{2})\d{2}(\d)(?:\d|X)$/;
42.//->把需要单独获取的部分用分组包起来,正则捕获的时候可以捕获到分组中的内容,如果加了分组,但是不想捕获,在该分组前面加 ?: 即可(只匹配不捕获)
43.
44./*
45. * 6、验证邮箱的
46. */
47.var reg = /^\w+((-\w+)|(\.\w+))*@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
正则的捕获
exec:可以实现正则的捕获,每一次执行exec只能捕获到一个匹配的结果,而且结果是一个数组
第一项:当前正则捕获的内容(字符串)
index:当前正则捕获的起始索引
input:当前操作的原始字符串
1.var reg = /\d+/; //->包含1到多个数字
2.var str = 'zhufeng2017peixun2018';
3.reg.exec(str); //->["2017", index: 7, input: "zhufeng2017peixun2018"]
4.reg.exec(str); //->["2017"...]
5.
6./*
7. * 问题:当前正则执行一次exec只能捕获到一个匹配的内容,我执行两次exec,第二次捕获到的依然在还是第一次的结果,不管执行多少次exec,捕获到的依然都是第一个
8. * =>“正则捕获的懒惰性”
9. *
10. * lastIndex:下一次正则捕获的时候,在字符串中查找的开始位置索引
11. * 第一次查找之前,reg.lastIndex=0,也就是第一次是从字符串的开始位置查找的,所以找到的是2017
12. * 第一次执行exec结束后,reg.lastIndex值还是0,所以第二次依然是从字母串的开始位置找的,找到的当然还是2017
13. * ...
14. *
15. * 解决正则的懒惰性:
16. * 执行exec后,让lastIndex值变为当前这一次捕获的结束位置,这样下一次捕获的时候,就可以接着继续查找了(而不是从头开始了)
17. * =>我们只需要给正则加一个全局修饰符g,就可以在每一次执行exec后,自动修改它的lastIndex了
18. */
19.var reg = /\d+/g;
20.var str = 'zhufeng2017peixun2018';
21.
22.reg.lastIndex ->0
23.reg.exec(str); ->['2017'...]
24.
25.reg.lastIndex ->11
26.reg.exec(str); ->['2018'...]
27.
28.reg.lastIndex ->21
29.reg.exec(str); ->null 捕获不到
30.
31.reg.lastIndex ->0
32.reg.exec(str); ->['2017'...]
33.
34./*
35. * 上面的案例中,我们知道执行两次就可以捕获全了,但是如果你不知道具体要捕获多少次,我们该如何是好?
36. * => 接下来我们自己在RegExp的原型上扩展一个方法myExecAll,执行这个方法,可以把所有匹配的一次性都捕获到
37. */
38.//->str:需要捕获的原始字符串
39.RegExp.prototype.myExecAll = function myExecAll(str){
40. //->this:reg
41. //->为了防止不加g的时候,每一次捕获的都是第一个,导致死循环,我们在正则没有加g的时候执行一次即可
42. if(!this.global){
43. //->没有加g:执行一次exec即可
44. return this.exec(str);
45. }
46. //->已经加g了
47. var ary = []; //->存储所有捕获的结果
48. var res = this.exec(str);
49. while(res){
50. ary[ary.length]=res[0];//->把每一次捕获的结果存放在数组的末尾
51. res = this.exec(str);
52. }
53. return ary;
54.}
55.
56./*
57. * 生活如此美好,何必这么麻烦和纠结
58. * 字符串中有一个方法叫做match,执行这个方法,也可以把所有匹配的内容,一次性捕获到,但是前提正则也需要加g,不加g,也只能捕获第一个
59. */
60.var reg = /\d+/g;
61.var str = 'zhufeng2017peixun2018hahah2019heheh2020';
62.str.match(reg); //->['2017','2018','2019','2020']
63.
64./*
65. * 难道生活如此简单吗?
66. * match虽然很简单暴力,但是在需要捕获小分组内容的时候,就不太符合我们的需求了,因为match只能把大正则匹配捕获到,对于小分组匹配的无法捕获
67. */
68.var ary = ['zxt',28];
69.var str = 'my name is {0},i am {1} years old~~';
70.//->我们想把 {0} 替换成 ary[0]
71.//->我们想把 {1} 替换成 ary[1]
72.//->我们既要捕获到 {数字},也需要把里面的数字单独的获取到(因为这个数字可以充当我们在数组中获取内容的索引)
73.var reg = /\{(\d+)\}/g; //->大正则匹配的是‘一个大括号中包含数字’,第一个小分组匹配的是‘大括号中的那个数字’
74.
75.reg.exec(str); //->["{0}", "0"...] 第一项大正则匹配的结果,第二项第一个分组匹配的结果 ,也就是使用exec可以捕获到小分组匹配的内容
76.reg.exec(str); //->["{1}", "1"...]
77.
78.str.match(reg); //->["{0}", "{1}"] 使用match只能捕获到大正则匹配的,小分组匹配的获取不到
79.
80./*
81. * match并不是所有情况下,都捕获不到分组的内容,当只需要捕获一次就可以完成的时候(或者不加g的时候),match获取的结果和exec一样
82. */
83.var reg = /^(\d{6})(\d{4})(\d{2})(\d{2})\d{2}(\d{1})(?:\d|X)$/; //->身份证号码的正则
84.var str = '130828198802240761';
85.str.match(reg); //->["130828198802240761", "130828", "1988", "02", "24", "6"...]
86.
87./*
88. * test在某些时候,也是实现捕获的:test匹配的时候,也是把符合的找到了,我们就可以使用一些特殊的手段,把查找的内容取出来
89. */
90.var str = 'my name is {0},i am {1} years old~~';
91.var reg = /\{(\d+)\}/g;
92.
93.reg.test(str);
94.console.log(RegExp.$1);//->获取第一次捕获的时候,第一个分组中的内容($1) =>'0'
95.
96.reg.test(str);
97.console.log(RegExp.$1); //=>'1' 并且执行test,如果设置了g,也是可以修改lastIndex的
98.
99.reg.exec(str); //->null
上面是正则捕获:懒惰性,正则捕获还有一个特点:贪婪性
1.var str='zhufeng2017peixun2018';
2.var reg=/\d+/g;
3.reg.exec(str);//->['2017'...] 每次捕获的时候都是把当前正则匹配的最长结果捕获到 ->`贪婪性`
4.
5.//->取消贪婪性:在量词元字符后面加一个问号就可以了
6.//=>问号作用很多
7.//1、如果放在一个非量词元字符的后面,它本身就是代表出现零次或者一次的量词元字符
8.//2、如果出现在量词元字符的后面,它本身是取消捕获时候的贪婪性的
9.var str='zhufeng2017peixun2018';
10.var reg=/\d+?/g;
11.reg.exec(str); //->['2'...]
12.
13.//3、?: 只匹配不捕获
14.//4、?= 正向预查
15.//5、?! 负向预查