1.1 正则基础
- 正则的含义:由特定的符号组成的具有特殊含义的代码;
- 正则的目的:就是制定一些规则,来操作(校验/匹配,捕获)字符串的内容;只针对字符串;
- 正则的操作:
- 校验:
reg.test(str)
,返回值为布尔值;如/^2\d{2}/.test(xml.status);
,校验成功,满足规则,就返回true,不满足规则,就返回false; - 捕获:
reg.exec(str)
,返回值为一个数组;目的:用我制定的规则去捕获字符串中的内容,有就以数组的形式拿出来,没有就返回null;
- 校验:
- 字符串与正则配合的方法:
- match("在字符串中查找内容"): 使匹配,如果存在要查找的内容,则返回内容,如果不存在,则返回null;
- replace("被替换的内容","替换的内容"): 不会改变原字符串,返回一个新的字符串;
- search():搜索,找到返回其下标值,找不到返回-1;
- split(separator,limit):字符串转换为新数组,原字符串不会发生改变;
- separator: 分离器,用于分割字符串的字符;即将其转换为逗号;—可以取空字符“”;
- limit:可选参数,即分割几次,数值等于数组元素的个数;
- 字符串方法代码格式:
- str.match();
- str.replace();
- str.search();
- str.split();
- 正则的方法代码格式:
- reg.test();
- reg.exec();
1.2 正则校验(匹配)
- 校验test()方法讲解:
<script>
var reg=/圆梦源/;
//test:里面如果没有进行限制,只要里面有我要的内容,都是true;
console.log(reg.test("圆梦源"));//打印为true
console.log(reg.test("2322圆梦源dffd"));//打印为true
var reg2=/^圆梦源$/;
//test:"^"为开头,"$"为结尾,意思是对内容进行了限制,所以必须严格校验;
console.log(reg2.test("圆梦源"));//打印为true
console.log(reg2.test("2322圆梦源dffd"));//打印为false
</script>
1.3 正则创建的方式
- 创建正则的方式分为两种:字面量创建和实例创建
- 字面量创建:
var reg=/^2\d{2}/
;- 总结:字面量创建,斜杠中不加引号,代表的就是字符串;斜杠中如果加引号,引号算一个字符,代表自己的字符意义;注意,字面量创建中无法进行变量的拼接;
//1.字面量创建,var reg=/str/,斜杠中不加引号,代表的就是字符串; var str="圆梦源"; var reg=/str/;//此处str指的是一个字符串"str";而不是变量str; console.log(reg.test("str"));//打印为true; console.log(reg.test("圆梦源"));//打印为false; //2.字面量创建中,斜杠中如果加引号,引号算一个字符,代表自己的字符意义 var reg2=/"+str+"/;//此处的+号,是把前面的字符多写几个;"号,代表一个字符放在里面; console.log(reg2.test("str"));//打印为false; console.log(reg2.test("圆梦源"));//打印为false; console.log(reg2.test('""""strrrrr"'));//打印为true; console.log(reg2.test('dsfsfsd""""strrrrr"'));//打印为true;校验不严格,只要存在内容就行; //3.注意,字面量创建中无法进行变量的拼接;
- 实例创建:
var reg=new RegExp(" ")
;- 总结:括号中必须加引号,才代表字符串,如果不带引号,就是变量;实例创建可以进行变量拼接;
//1.实例创建中,var reg=new RegExp("str"),括号中必须加引号,才代表字符串,如果不带引号,就是变量; var str="圆梦源"; var reg3=new RegExp(str);//括号中不加引号,就指的是变量; console.log(reg3.test("圆梦源"));//打印为true; console.log(reg3.test("123圆梦源dfsd"));//打印为true; console.log(reg3.test("str"));//打印为false; //2. 实例创建中,括号里加引号,此时指的就是字符串,不再是变量; var str="圆梦源"; var reg4=new RegExp("str"); console.log(reg4.test('圆梦源'));//打印为false; console.log(reg4.test("str"));//打印为true; //3.实例创建可以进行变量拼接; var str="圆梦源"; var reg6=new RegExp("ti"+str+"an");//变量拼接 console.log(reg6.test("ti圆梦源an"));//打印为true;
- 字面量创建和实例创建的区别:
- 字面量创建无法拼接变量,实例创建可以拼接变量;
- 字面量创建不需要转义,实例创建需要转义,如“\d”等带斜杠的元字符需要转义,前面加一个斜杠;
var reg=/^2\d{2}$/;//字面量创建中,特殊符号不需要转义; console.log(reg.test("200"));//结果为true; var reg2=new RegExp("^2\\d{2}$");//实例创建中,特殊符号需要转义,如"\d"前面加"\"; console.log(reg2.test("200"));//结果为true;
- 字面量创建:
1.4 正则表达式的组成
- 正则表达式组成:由元字符和修饰符两部分组成;如代码:
var reg=/^2\d{2}/g
;- 元字符:就是包含在两个斜杠之间的字符;
- 修饰符:就是斜杠外面的字符;
- 元字符:包含特殊含义的元字符和量词元字符
- 特殊含义的元字符:1)\转义;2)|或;3)()分组;4).除了\n以外的其他字符;5)\n 换行;6)\b 开头结尾和空格;7)^开头;8)$结尾 9)\s 空格;10)\S 非空格;11)\d 数字 12)\D 非数字;13)\w数字,字母,下划线; 14)\W 非数字,字母,下划线;15)[a-z]a到z之间的小写字母; 16)[^a-z] 非a到z之间的小写字母; 17)[abc] 包含abc三个字母中的任何一个,只能是一个; 18)[^abc] 除了abc三个字母;
- 量词元字符:1)* 0到多次; 2)+ 1到多次; 3)? 0或1; 4){n} 正好n次; 5){n,} 最少n次;n次到多次; 6){n,m} n次到m次;
- 修饰符:1)g 全局; 2)m 换行; 3) i 忽略大小写;
- 知识点:
- 小括号的用法:
- 提高优先级:
/^(18|19)$/
;验证18或19;
//目的:验证18或19 var reg=/^18|19$/;//分析:1加8或1加9,以1开头,以9结尾; console.log(reg.test("18219"));//结果为true; console.log(reg.test("119"));//结果为true; //注意:当使用|的时候必须加小括号; //正确写法: var reg1=/^(18|19)$/; console.log(reg1.test("189"));//结果为false; console.log(reg1.test("18"));//结果为true;
- 分组的作用;
- 小分组的作用;用于exec捕获;
- 提高优先级:
- 中括号的用法:
- 中括号[]的用法:中括号中不会出现两位数;只能出现一个;
//[abc]意思是abc中的任何一个;不会出现两个; var reg=/^[11-89]$/;//分析:1或1-8或9,三者中的任何一个 console.log(reg.test("1"));//结果为true; console.log(reg.test("6"));//结果为true;6在1-8之间; console.log(reg.test("11"));//结果为false;11不在三者之间;
- 中括号[]里面的字符意义会发生改变,分为两种,
- 如"+","."这些元字符,代表加,小数点;都不用加转义符;但是在其他的时候必须加转义符才能代表加,小数点的意思;
- 对比1:
[+-]
指的是+或-,二者任何一个;此时中括号中的+号,不用加转义符,就代表加号的含义; - 对比2:
(\+|-)
指的是+或-,二者任何一个;此时在小括号中的+号需要添加转义符;才代表加号的含义;
- 对比1:
- 如"\w","\s","\d"这些元字符,带斜杠的仍然代表元字符的含义;
- 如"+","."这些元字符,代表加,小数点;都不用加转义符;但是在其他的时候必须加转义符才能代表加,小数点的意思;
- 中括号[]的用法:中括号中不会出现两位数;只能出现一个;
- 中括号和小括号的共同点:是在使用或的时候,功能是一样的;都代表两者其一;
- 中括号:
[ab]
指的就是a,b二者中任何一个; - 小括号:
(a|b)
指的也是a,b二者中任何一个; - 弊端:当a,b为数字时,必须是一位数时,才能用中括号,如果为两位数,只能用小括号;如
[1234]
代表的意思是1234四位数中的任何一个数;而(12|34)
代表的是12或34; - 注意:尽量不要用小括号,因为在exec方法捕获时,会对小括号进行小分组;会导致错乱;可以通过添加"?:"来解决,只匹配不捕获;
- 中括号:
- 量词元字符"?"问号的用法:
- 代表可有可无;如有效数字正则表达式中的使用;
- 放在正则捕获中的量词元字符后面,添加后,来解决正则捕获的贪婪性;如捕获数字时,只捕获一个数字时的使用;
- 小括号的用法:
1.5 正则表达式实际应用
- 有效数字的正则表达式
- 代码:
var reg=/^[+-]?(((\d)|([1-9]\d+))(\.\d+)?)$/
或var reg=/^(\+|-)?(((\d)|([1-9]\d+))(\.\d+)?)$/
(其中加号要用转义符); - 解读:
-
^
指开头,$
指结尾 -
+
和-
都可以,所以用[+-]
,可有可无,用?
- 数字分为整数和小数,用
()()
- 整数分为两种,一位数,两位数或更多;所以用或,即
()|()
; - 一位数()可以是0-9之间的任何一个数,所以用
\d
; - 两位数或多位数,第一位不能是0,所以需要1-9之间的数字,用
[1-9]
;第二位可以是0-9之间的数字,用\d
,可以是三位数或更多位,用+
; - 小数可有可无,用
?
;小数中分为小数点和数字,其中小数点用转义符\.
来组合,数字可以是0-9之间的任何数字,所以用\d
,可以是多位数,用+
;
-
- 代码:
- 电话号码的正则表达式
- 代码:
var reg=/^1\d{10}$/
- 解读:
^1
指以1开头,\d
指0-9之间的数字,{10}
指正好10位数字,$
指结尾;
- 代码:
- 邮箱的正则表达式
- 代码:
var reg=/^([\w.-]+)@([a-zA-Z0-9]+)((\.[a-zA-Z]{2,4}){1,2})$/
- 分析:邮箱可能出现的情况:zhan233f_sdi-dfjeif.djife @ qq/163 .com/.cn/.blog
- 解读:
- 邮箱分为四部分
- 第一部分:@前面的部分。有可能出现的情况:小写字母a-z;大写字母A-Z;数字0-9;下划线_;符号-;符号.
- 用
[\w.-]+
表示上面出现的情况;- 其中“小写字母a-z;大写字母A-Z;数字0-9;下划线_;”,用
\w
表示; - 其中“符号-;符号.”,用
[.-]
表示,中括号的意思是三者出现任何一个; -
+
的意思是可以出现1到多个;
- 其中“小写字母a-z;大写字母A-Z;数字0-9;下划线_;”,用
- 用
- 第二部分:
@
符号,直接字符串拼接; - 第三部分:qq或QQ或163或者其他,但是包括小写字母a-z;大写字母A-Z;数字0-9;不包括下划线,所以不能用
\w
;-
[a-zA-Z0-9]
指的就是“小写字母a-z;大写字母A-Z;数字0-9”; -
+
指的是可以出现1到多次;
-
- 第四部分:“.com/.cn/.blog”,其中可能出现".com"或".com.cn"或".com.blog"三种情况
- 先创建".com或.cn或.blog",
\.
代表小数点,[a-zA-Z]
代表所有的大小写字母,{2,4}
指的是字母出现的次数只能在2到4之间;不能是+
; - 所以
(\.[a-zA-Z]{2,4})
代表的是".com或.cn或.blog"; -
{1,2}
指的是".com或.cn或.blog"出现的次数,只能出现1到2次;如".com"或".com.cn"或".com.blog"三种情况
- 先创建".com或.cn或.blog",
- 验证代码:
var reg=/^([\w.-]+)@([a-zA-Z0-9]+)((\.[a-zA-Z]{2,4}){1,2})$/; console.log(reg.test("135865985@qq.com"));//结果为true; console.log(reg.test("135865985@163.com.cn"));//结果为true; console.log(reg.test("135865985@qq.com.blog"));//结果为true; console.log(reg.test("135865985@qq.com.blogg"));//结果为false;因为.blogg位数超过四位;
- 代码:
- 中文的正则表达式
- 第一个汉字:“一”,代码:
\u4e00
; - 最后一个汉字:“龥”,代码:
\u9fa5
; - 实例:二到四位的汉字;代码:
var reg=/^[\u4e00-\u9fa5]{2,4}$/
- 第一个汉字:“一”,代码:
- 数字18到65之间的正则表达式
- 分析:将其分解为三部分,18-19,20-59,60-65
- 代码:
var reg=/^((18|19)|([2-5]\d)|(6[0-5]))$/
;注意:有或出现必须加小括号; - 解读:
-
(18|19)
指18或19之间一个数; -
[2-5]\d
指第一位为2到5之间,第二位为0-9之间数字; -
6[0-5]
指第一位为6,第二位为0-5之间的数字;
-
- 身份证号码的正则表达式
- 简单的正则表达式
- 分析:身份证总共18位,最后一位可能是数字也可能是字母X
- 知识点:小括号与中括号中解决或的问题的方法,以及使用小括号的弊端;
- 代码:
var str="130216192305253234"; var reg=/^\d{17}(\d|X)$/; console.log(reg.exec(str));//结果为:["130216192305253234", "4", index: 0, input: "130216192305253234", groups: undefined] //此时用exec会出现问题,当用到或的时候,需要用小括号,但是在exec中会把小括号作为小分组,拿出来;所以会多一项"4"; var reg1=/^\d{17}[\dX]$/; //避免使用小括号,可以使用中括号,来解决或的问题; console.log(reg1.exec(str));//结果为:["130216192305253234", index: 0, input: "130216192305253234", groups: undefined]
- 获取详细信息的正则表达式
- 分析:身份证号码每一位都有其含义,所以需要小分组将其分别获取,分类如:两位省,四位市县,四位年,两位月,两位日,后四位(分为两位户口所在地编码,一位奇偶性别,最后一位根据前面17位计算出来代表个人信息的)
- 代码:
var str="130216192305253234"; var reg2=/^(\d{2})(\d{4})(\d{4})(\d{2})(\d{2})(\d{2})(\d)(\d|X)$/; console.log(reg2.exec(str));//结果为:["130216192305253234", "13", "0216", "1923", "05", "25", "32", "3", "4", index: 0, input: "130216192305253234", groups: undefined];
- 简单的正则表达式
1.6 正则捕获
- 正则中的捕获,主要讲三个方法:
- exec: reg.exec(str);——正则的方法;
- match: str.match(reg);——字符串的方法;
- replace: str.replace(reg,xxxx);——字符串的方法;
1.6.1 正则exec方法解读
- 定义:exec是正则的方法,每次捕获只能捕获一个满足正则的内容,然后返回的结果是个数组,默认情况下,数组有4项:
- 第一项:符合大正则的内容;(包含小分组内容)
- 第二项:如果存在小分组,则第二项内容为小分组的内容;如果存在多个小分组,那么会依次类推到第三项等等;
- 第三项:index:对应的值为查找到的内容开始字符所对应的索引;(位置)
- 第四项:input:原始字符串;
- 代码:
var str="huadianxiehe2018zhanwang2019huigu2017huadianxiehe2015"; var reg=/huadianxiehe(\d+)/g;//此时()为小分组,所以得到的数组中第二项为小分组内容; console.log(reg.exec(str));//结果为:["huadianxiehe2018", "2018", index: 0, input: "huadianxiehe2018zhanwang2019huigu2017huadianxiehe2015", groups: undefined] console.log(reg.exec(str));//结果为:["huadianxiehe2015", "2015", index: 37, input: "huadianxiehe2018zhanwang2019huigu2017huadianxiehe2015", groups: undefined]
- 正则捕获有两大特点:
- 懒惰性:每次找的时候都是从0开始找;
- 解决措施:添加修饰符全局g;目的使其按顺序找;需注意:当查找到最后一个满足条件的表达式后,会输出null,然后再查找的时候,会重头开始查找,无限循环;
- 知识点:修饰符g的作用,以及exec捕获的方式和返回的数组形式;
- 代码对比:
<script> var str="huadianxiehe2018zhanwang2019huigu2017"; //1.不添加全局g,每次查找时,都从0开始查找; var reg=/\d+/; console.log(reg.exec(str));//结果为:["2018", index: 12, input: "huadianxiehe2018zhanwang2019huigu2017", groups: undefined] console.log(reg.exec(str));//结果为:["2018", index: 12, input: "huadianxiehe2018zhanwang2019huigu2017", groups: undefined] //2. 添加全局g,每次按顺序向后找,需注意:当查找到最后一个满足条件的表达式后,会输出null,然后再查找的时候,会重头开始查找,无限循环; var reg=/\d+/g; console.log(reg.exec(str));//结果为:["2018", index: 12, input: "huadianxiehe2018zhanwang2019huigu2017", groups: undefined] console.log(reg.exec(str));//结果为:["2019", index: 24, input: "huadianxiehe2018zhanwang2019huigu2017", groups: undefined] console.log(reg.exec(str));//结果为:["2017", index: 33, input: "huadianxiehe2018zhanwang2019huigu2017", groups: undefined] console.log(reg.exec(str));//结果为:null; console.log(reg.exec(str));//结果为:["2018", index: 12, input: "huadianxiehe2018zhanwang2019huigu2017", groups: undefined] </script>
- 贪婪性:在正则代码中添加"+"号后,就会把所有的输出来,所以比较贪婪;
- 解决措施:在量词元字符"+"后面,添加量词元字符"?";
- 知识点:量词元字符"?"的应用
- 代码对比:
var str="huadianxiehe201823243zhanwang2019huigu2017"; var reg=/\d+/g; console.log(reg.exec(str));//结果为:["201823243", index: 12, input: "huadianxiehe201823243zhanwang2019huigu2017", groups: undefined] //分析:添加+号后,exec会一下将201823243全部拿出来,显示贪婪; var reg1=/\d+?/g; console.log(reg1.exec(str));//结果为:["2", index: 12, input: "huadianxiehe201823243zhanwang2019huigu2017", groups: undefined] console.log(reg1.exec(str));//结果为:["0", index: 13, input: "huadianxiehe201823243zhanwang2019huigu2017", groups: undefined] //分析:在+号后面添加?号,会解决它的贪婪性,让其每次都输出一个数字; //修改:如果想要达到捕获的目的,一个一个数字的获取,正则表达式可以写成 reg=/\d/g;
- 懒惰性:每次找的时候都是从0开始找;
- 正则属性方法:
- lastIndex属性:
- 属性值:若正则表达式中在未添加全局g时,每次exec捕获都从0开始,此时的lastIndex值都是0;
- 属性值:若正则表达式中添加全局g后,指最后一次exec捕获内容后,开始下一次捕获时,开始查找的字符位置的索引值;需注意:当查找到最后一个满足条件的表达式后,会输出null,此时lastIndex值为0;继续查找,就会重头开始查找,无限循环;
- 代码:
<script> var str="huadianxiehe201823243zhanwang2019huigu2017"; var reg=/\d+/g; console.dir(reg); console.log(reg.lastIndex);//结果为:0; console.log(reg.exec(str));//结果为:["201823243", index: 12, input: "huadianxiehe201823243zhanwang2019huigu2017", groups: undefined] console.log(reg.lastIndex);//结果为:21; console.log(reg.exec(str));//结果为:["2019", index: 29, input: "huadianxiehe201823243zhanwang2019huigu2017", groups: undefined]; console.log(reg.lastIndex);//结果为:33; console.log(reg.exec(str));//结果为:["2017", index: 38, input: "huadianxiehe201823243zhanwang2019huigu2017", groups: undefined]; console.log(reg.lastIndex);//结果为:42; console.log(reg.exec(str));//结果为:null; console.log(reg.lastIndex);//结果为:0; //当查找完后,会重复查找; console.log(reg.exec(str));//结果为:["201823243", index: 12, input: "huadianxiehe201823243zhanwang2019huigu2017", groups: undefined]; console.log(reg.lastIndex);//结果为:21; </script>
- lastIndex属性:
- 实例1
- 需求:获取字符串中所有的数字,组成一个数组
- 代码:
<script> var str="huadianxiehe2018zhanwang2019huigu2017"; var reg=/\d+/g; var ary=[]; var res=reg.exec(str); while(res){ ary.push(res[0]); res=reg.exec(str);//注意:必须重新赋值,然后再判断; } console.log(ary);//结果为:["2018", "2019", "2017"]; </script>
1.6.2 字符串match方法解读
- 定义:是字符串的方法,每次能得到所有符合正则的内容,并且以一个新数组的形式返回;如果没有符合规则的内容,返回null;
- 代码:
var str="huadianxiehe2018zhanwang2019huigu2017huadianxiehe2015"; var reg=/\d+/g; console.log(str.match(reg));//结果为:["2018", "2019", "2017", "2015"];
1.6.3 exec方法与match方法的区别
- exec方法与match方法的区别:
- exec方法是RegExp类原型上的方法;match方法是字符串原型上的方法;
- exec方法和match方法,在查找的时候,正则表达式中,如果不添加全局g,则两个方法拿到的结果是相同的,都是一个数组,里面有三项;
- exec方法每次只能拿到一个值;match方法能拿到所有值(前提是正则表达式中添加全局g),并以新数组的形式返回;针对的都是字符串;
- exec方法既能拿到大正则,也能拿到小分组;match方法只能拿到大正则,无法拿到小分组;
- 实例:利用exec方法实现match功能
<script> var str="huadianxiehe2018zhanwang2019huigu2017"; var reg=/\d+/g; //需求:利用exec方法实现match功能 //第一反应:match方法是谁的方法?——字符串String类原型prototype上的公有属性; //第二反应:match方法中的this是谁?——this指向字符串实例; //第三反应:match方法有什么功能,如何用exec方法去封装; //分析:match方法作用是,获取str中所有满足正则表达式reg要求的内容,作为数组元素,返回一个数组; //进而就决定了函数的参数是reg表达式,返回值为数组,函数中this指向字符串实例; String.prototype.Match=function (Reg) { //此时this指向字符串实例,所以就可以用this来代表外面的字符串 //1.先拿到第一次的exec返回值; var ary=[]; var ree=Reg.exec(this); //2.通过while循环依次往数组中放我们找到的值,当没有找到时,会返回null; while(ree){ ary.push(ree[0]); ree=Reg.exec(this); } //3.返回值; return ary;//此时如果不添加返回值,会默认返回this实例对象,此处添加返回值为数组对象,引用数据类型,会重新赋值数组新地址; }; var res=str.Match(reg); console.log(res); </script>