老程序员分享:JS基础知识(正则)

简介: 老程序员分享:JS基础知识(正则)

正则


正则的基础知识


什么是正则


正则的元字符和修饰符


正则捕获


正则捕获的懒惰性


使用字符串中的match实现捕获


使用test实现捕获


正则案例


正则创建方式


问号传参面试题


正则


正则的基础知识


什么是正则?


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


1、正则匹配


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


2、正则捕获


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


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


1


2


正则的元字符和修饰符


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


修饰符


g(global):全局匹配


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


m(mutiline):多行匹配


元字符


【量词元字符】


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


?:出现0到1次


:出现0到多次


{n}:出现n次


{n,}:出现n到多次


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


【特殊意义的元字符】


-\ 转义字符


-.除了\n(换行符)以外的任意字符


-\d 匹配一个0-9的任意字符


\D 匹配一个非0-9的任意字符


\w 匹配一个【0-9a-zA-Z_】之间的任意字符


\s 匹配一个任意空白符


\b 匹配一个边界符(单词的左右,-的左右两边)


x|y 匹配两者中的其中一个


【a-z】 匹配a-z中的任意一个字符


【^a-z】 匹配非a-z中的任意一个字符


【xyz】 匹配xyz中的其中一个


【^xyz】匹配除了xyz以外的任意字符


()正则小分组


^ 以某一个元字符开始


$ 以某一个元字符结束


?: 只匹配不捕获


?=正向预查


?! 负向预查


var reg=/^\d$/;


//说明以数字开头,以数字结尾 ,且只包含一个数字


var reg=/^2.3$/;//.代表除了\n以外的任意字符


reg.test(2.3); true


1


2


3


4


5


var reg=/^18|19$/;// x|y的情况


// 18或19


// 以1开头以9结尾,中间是8或1


// 以18开头或以19结尾


//


var reg=/^(18|19)$/;//18或19


//()正则里的分组,大正则里的小分组,我们可以使用它改变默认的优先级


//此时只//代码效果参考:http://www.lyjsj.net.cn/wx/art_23943.html

有18或者19符合规则

1


2


3


4


5


6


7


8


()


- ()正则里的分组,大正则里的小分组,我们可以使用它变默认的优先级


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


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


分组引用:\1 表示出现和第1个分组一模一样的字符


var reg=/^(【a-z】)(【a-z】)\2(a-z)$/;// 类似于food week feel oppo等都符合该正则


1


【 】


【xyz】 【^xyz】 【^a-z】


var reg=/^【a-zA-Z0-9】$/;//等同于\w


【 】中出现的元字符,一般都代表本身的含义var reg=/^【.?+】$/里面的.代表.本身


//需求类的命名规则:数字字母下划线 ,(//代码效果参考:http://www.lyjsj.net.cn/wz/art_23941.html

-不能作为开头)

var reg=/^\w【\w-】$///不要让-出现在中间就可代表其本身的含义,出现在中间表示范围链接符


var reg=/^【18-65】$/代表的意思:1或8~6或5中的任意一个字符 ,中括号出现的18不代表数字18而是1或者8,当前正则非法


18-65岁份三阶段


18~19 (18|19)


20~59(【2-5】\d)


60~65(6【0-5】)


验证是否为有效数字


可能正数,可能是负数


整数或小数


只要出现小数点,后面至少出现一位


小数点前必须有数字


var reg=/^-?(\d|(【1-9】\d+)(.\d+)?$/


var reg=/^1\d{10}$/


1


中文姓名


/^【\u4E00-\u9FA5】$/ :中文汉字的正则


var reg = /^【\u4E00-\u9FA5】{2,10}(·【\u4E00-\u9FA5】{2,10})?$/;


尼古拉斯·王武


1


2


3


邮箱


reg=/^\w+((-\w+)|(.\w+))@【A-Za-z0-9】+((.|-)【A-Za-z0-9】+).【A-Za-z0-9】+$/


分析需求:


以数字字母下划线开头


@前面可以是 数字、字母、下划线、-、. 这些符号


不能把 -和. 连续出现,出现一次后面必须跟数字字母下划线



@后面的部分支持


企业邮箱


.com.cn 多域名情况


/


//这样写不仅可以匹配,而且以后捕获的时候,不仅可以把大正则匹配的结果捕获到//代码效果参考:http://www.lyjsj.net.cn/wx/art_23939.html

,里面的每一个小分组也可以分别捕获到"分组捕获"

1


2


3


4


5


6


7


8


9


10


11


身份证号


var reg=/^(\d{6})(\d{4})(\d{2})(\d{2})(\d{2})(\d)(X|\d)$/


1


正则捕获


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


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


当我们执行reg.exec(str)的时候,


- 1、先去验证当前字符串和正则是否匹配,如果不匹配则返回结果null;


- 2、如果匹配,从字符串最左边开始,向右查找匹配内容,并把匹配内容返回


exec捕获到的结果的格式:


获取的是一个数组


数组中的第一项是当前本次大正则匹配的结果


index:记录了本次捕获到结果的起始的索引


input:当前正则操作的原始字符串


如果当前正则当中有分组,获取的数组中,从第二项开始,都是每个小分组


执行一次exec只能把符合正则规则的一个内容捕捉到,若果还有其他符合规则的, 需要再次执行exec才有可能捕获到;


正则捕获的懒惰性


正则为什么会存在懒惰性


正则本身有一个属性:lastIndex(下一次正则在字符串匹配查找时的开始索引)


默认值:0,从字符串的第一个字符开始查找匹配的内容


默认不管执行多少次exec,正则的lastIndex值都不会变,也就是还是从第一个字符开始查找


并且当我们手动改变last Index的值时,不会起任何作用


由此导致:执行一次exec捕获到第一个符合规定的内容,第二次执行exec,捕获到的依然是第一个匹配内容,后面的无论执行多少次都捕获不到


解决正则的懒惰性


在正则的末尾加修饰符g(全局匹配)


加了修饰符g,每次exec结束后,浏览器会默认把lastIndex的值进行修改,下一次从上一次结束的位置开始查找,所以可以得到后面匹配的内容了


var reg=/\d+/g;//开启全局匹配


1


2


exec有自己的局限性,执行一次exec只能捕获到一个结果,如果想要全部捕获到,就要执行多次,下面封装的myExecAll方法,可以将正则匹配的全部内容捕获到


RegExp.prototype.myExecAll=function(){


//this 是当前需要处理的正则


//str是当前需要处理的字符串


var str=agruments【0】||'';


var result=【】;


//首先判断是否加了全局修饰符G,如果没有加,我们直接将第一次的结果返回即可


if(!this.global){


return this.exec(str);


}


var ary=this.exec(str);


while (ary){//(等同于ary!==null:可以捕获到内容,我们继续下一次捕获


result.push(ary【0】);//第一项为匹配到的结果


ary=this.exec(str);//继续执行下一次捕获


}


return result;


};


1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


使用字符串中的match实现捕获


使用字符串match捕获,


- 如果正则加了g,会捕获到所有匹配结果


- 如果不加g,则只会捕获到第一个匹配结果


match的局限性


- 在加了修饰符g的情况下,·执行match只会把大正则匹配的结果捕获到,对于小分组里的匹配结果会自动忽略·


使用test实现捕获


不管是正则的匹配还是捕获,在处理的时候是没有区别的,从字符串里的第一个字符开始查找符合规则的字符,如果可以找到,则返回true,exec捕获返回捕获的内容,如果没有找到,test返回false,exec捕获返回null


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


var str='my name is {0}~~';s


var reg=/{(\d+)}/g;


if(reg.test(str)){//->lastIndex=0


console.log(reg.exec(str));//->null lastIndex值被修改,向后查找,无匹配


}


1


2


3


4


5


6


test不仅可以找到匹配的内容,也肯能将匹配的内容获取


console.log(RegExp.$1);//获取当前匹配内容的第1个小分组;


1


2


所有支持正则的方法,都可以实现字符串的捕获(一般都是字符串方法)


字符串中常见的支持正则的方法


- match


- split


- replace


split


var str='name="珠峰"&age=8';


str.split(/(&|=)/); //使用split进行字符串进行拆分的时候,如果正则包含小分组,会把小分组的内容捕获到,放在最后的数组中


//本案例()只是为了改变优先级,但我们只想匹配不想捕获分组里的内容,?:可以解决


str.split(/?:(&|=)/);// 这样浏览器就不会把小分组的内容捕获到;


1


2


3


4


5


要计算是第几个分组,从左到右数( =>半括号即可


replace


字符串中原有字符的替换


str.replace(old,new)


var str='珠峰2011珠峰1021';


str=str.replace('珠峰','珠峰培训');


str.replace(/珠峰/g,'珠峰培训');


1


2


3


4


在不使用正则的情况下,执行一次replace只能替换一个原有字符,第二次执行replace,依旧是从第一个字符开始查找,类似于正则的懒惰性


工作中,replace都是和正则一起搭配使用


replace原理:


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


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


- 正则加g,把当前所有和正则匹配的内容都捕获到,并替换成新字符


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


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


- 不仅执行这个函数,还把正则本次捕获的结果(同执行exec捕获的结果,包含小分组)当做实参传递给这个函数(这样就可以在函数中获得这些值,这些值就是正则每一次捕获的结果)


正则捕获方法统计


方法名不加g加g


exec


懒惰性,只能到捕获第一个匹配值包括小分组


多次捕获可得所有匹配字符,包括小分组


match


懒惰性 同上


一次捕获到所有匹配字符,但不能匹配到小分组


test


懒惰性同上


多次捕获可得全部内容,每执行一次test,就console.log(RegExp.$1),可得当前匹配字符


replace


懒惰性,只替换一个


全部替换


正则案例


=>单词首字母大写


var str='my name is zhu-feng-pei-xun,i am 8 years old,i am qian duan pei xun no1!';


//先把混淆边界符的-替换为下划线


str=str.replace(/-/g,);


//通过边界符匹配到每个单词


str=str.replace(/\b(\w)(\w*)\b/g,function(){


console.log(agruments);


return agruments【1】.toUpperCase()+agruments【2】;


})


str=str.replace(//g,-);


1


2


3


4


5


6


7


8


9


10


11


var str='2017-11-07 16:30';//改写成2017年11月07日16时30分


//replace


1


2


3


模板匹配()


var template='{0}年{1}月{2}日 {3}时{4}分{5}秒';


var reg=/\d+/g;


var ary=str.match(reg)


var str='2017-11-07 16:30';


//先将str的有效数字匹配出来,得到一个数组(match)


//其次 将template中的{0}与之数组对应索引替换(/{(\d)});


var template=template.replace((/{(\d)}),function(){


var index=arguments【1】;//有多少个匹配的字符串,函数就会被执行多少次,这是每次匹配的小分组,即0/1/2...


var value=ary【index】;//将数组中对应索引的值拿出来


return value;


})


1


2


3


4


5


6


7


8


9


10


11


12


正则创建方式


字面量方式


var reg=/\d+/img;


1


2


构造函数创建


new RegExp('元字符','修饰符')


var reg= new RegExp('\d+','g');


//将一个\换成\才是转义字符的意思,''里面放的都是字符串


1


2


3


4


构造函数可以动态加入一个变量的值


问号传参(面试题)


let url = '';


//实现方法


String.prototype.myQueryURLParameter = function myQueryURLParameter() {


let reg = /【?&】(【^?&=】+)(?:=(【^?&=】*))?/g,


obj = {};


this.replace(reg, (...arg) => {


let 【, key, value】 = arg;


obj【key】 = value;


})


return obj;


};


//方法调用


let result = url.myQueryURLParameter();


=》{ a: '1', b: '2', c: '', d: 'xxx', e: undefined }

相关文章
|
3月前
|
存储 JavaScript 前端开发
后端程序员的前端基础-前端三剑客之JavaScript
后端程序员的前端基础-前端三剑客之JavaScript
31 4
|
3月前
|
JavaScript 前端开发 程序员
程序员必看:利用JavaScript的算术运算符大幅提升代码效率?
程序员必看:利用JavaScript的算术运算符大幅提升代码效率?
|
5月前
|
Web App开发 JavaScript 前端开发
程序员必知:【three.js练习程序】创建地球贴图
程序员必知:【three.js练习程序】创建地球贴图
49 0
|
5月前
|
自然语言处理 JavaScript 前端开发
【JavaScript】JavaScript基础知识强化:变量提升、作用域逻辑及TDZ的全面解析
【JavaScript】JavaScript基础知识强化:变量提升、作用域逻辑及TDZ的全面解析
63 3
|
5月前
|
前端开发 JavaScript 程序员
探索JavaScript宝库:打开基础知识与实用技能之门(数据类型与变量+ 条件与循环+函数与模块+DOM+异常+ES6)
探索JavaScript宝库:打开基础知识与实用技能之门(数据类型与变量+ 条件与循环+函数与模块+DOM+异常+ES6)
33 0
|
5月前
|
缓存 JavaScript 前端开发
老程序员分享:js刷新页面得重新加载和页面的刷新
老程序员分享:js刷新页面得重新加载和页面的刷新
40 0
|
5月前
|
缓存 JavaScript 前端开发
程序员必知:广告等第三方应用嵌入到web页面方案之使用js片段
程序员必知:广告等第三方应用嵌入到web页面方案之使用js片段
75 0
|
5月前
|
JavaScript 前端开发 IDE
程序员必知:WPSJSA宏编程(JS):1.初识
程序员必知:WPSJSA宏编程(JS):1.初识
282 0
|
5月前
|
JavaScript 前端开发 小程序
老程序员分享:js中自然日的计算
老程序员分享:js中自然日的计算
52 0
|
5月前
|
JavaScript 程序员
老程序员分享:JS日期格式转换
老程序员分享:JS日期格式转换
82 0