正则是一个前端必须掌握的知识。可是因为用的少,忘了记,记了忘,致使面试常常坐蜡。这里上篇先介绍正则的规则,下篇结合一些具体题目,带你们从新学习巩固一下正则,争取面试给本身加分。前端
介绍:用来处理字符串的一个规则
正则:判断一个字符串是否符合咱们的规则-> reg.test(str)
捕获:把字符串中符合咱们规矩的子字符捕获到 ->reg.exec(str)面试
实例建立和使用字面量,可是要注意使用实例建立正式是可使用变量进行拼接的
正则表达式
正则表达式由两种基本字符类型组成,原义文本字符和元字符windows
元字符:在正则表达式中具备特殊意义的字符,原义字符变元字符加''
^ 开头 $ 结尾 b 单词边界 B非单词边界
/\bengineer$/.test('I am an engineer') //true
*: 零次到屡次
+:1次到屡次
?: 0次或者1次
{n} 出现n次
{n,m} 出现n次到m次
let reg = /1\d{10}$/ //验证手机号,第一位是1
[a-z] a-z之间的任何一个字符
[a-zA-Z] a-z以及A-Z之间的任何一个字符
'a1b2C3C4'.replace(/[a-z]/g,'Q') //"Q1Q2C3C4"
x|y :x或y中的一个 [xyz]: x或者y或者z中的一个 [^a-z] 除了a-z之外的任何一个字符 [^xyz] 除了xyz之外的任何一个字符
// . 除了回车和换行的全部字符 [^\r\n] // \d 数字 [0-9] // \s 空白字符 [\t\n\x0B\f\r] // \w 单词 字符[A-Za-z0-9_] //注意,.的范围要比\W范围大,由于它还包括制表符之类的`注意只是一个字符而不是一个单词` 'hello'.replace(/\w{2}$/g,'x') //helx
正则对象属性
修饰符:数组
i 忽略大小写
g 全局匹配
m 多行匹配
注意这里设置了,在正则对象里的相应属性会改变
var a = /\d/g a.global //true var b = /\d/ b.global //false
正则对象属性:学习
global ignore case multiline lastIndex sourse
注意,lastindex在全局匹配里面会匹配一次改变一个,超出匹配范围会被清零
var reg1 = /\w/ var reg2 = /\w/g reg1.test('a') //true //reg1.lastIndex //0 reg1.test('a') //true //reg1.lastIndex //0 reg1.test('a') //true //reg1.lastIndex //0 reg2.test('a') //true //reg2.lastIndex //1 reg2.test('a') //false //reg2.lastIndex //0 reg2.test('a') //true //reg2.lastIndex //1 reg2.test('a') //false //reg2.lastIndex //0
正则默认是贪婪模式,会按尽量多的匹配,在量词后面加?能够取消贪婪性测试
123456.replace(/\d{3,6}/g,'x') //因为有贪婪性,按6次匹配,结果为'x' '123456'.replace(/\d{3,6}?/g,'x') //此时没有贪婪性,可是有全局匹配,结果为'xx' '123456'.replace(/\d{3,6}?/g,'x') //此时没有贪婪性,局部匹配,结果为'x456'
或|,左边的单词(分组)或者右边的单词(分组)出现均可以
分组的目的是为了更好的捕获,增长控制力 分组能够用num表明注意或|的优先级是最低的,比字符串串接的优先级还要小,因此有/Bayron|casper/是匹配两个单词而不是n或者c的状况
spa
bary{3} //y重复3次 (bary){3} //单词重复3次 Bayron|casper //两个单词的或 Bayr(on|ca)sper //中间两个字母随便出现哪一个都行,注意同时出现两个是不匹配的 'Bayroncasper'.replace(/Bayr(on|ca)sper/g,'x') //"Bayroncasper" 'Bayrcasper'.replace(/Bayr(on|ca)sper/g,'x') //"x"
正则匹配的方向是从左向右,因此向右是前瞻,向左是后顾,断言能够理解为规则,可是不参与匹配
(正向)前瞻就是在正则表达式匹配到规则的时候,向前检查是否符合断言
(正向)后顾就是在正则表达式匹配到规则的时候,向后检查是否符合断言
(负向)... 就是正则表达式匹配到规则的时候,向(前)后检查是否不符合断言3d
'Windows2000'.replace(/Windows(?=2000)/g,'x') //"x2000" 正向前瞻 ?= 'Windows2000'.replace(/Windows(?!2000)/g,'x') //"windows2000" 负向前瞻 ?! 'I has Windows2000'.replace(/(?<=I has )Windows/g,'x') //"I has x2000" 正向后顾 ?<= 'I has Windows2000'.replace(/(?<!He has )Windows/g,'x') //"I has x2000" 负向后顾 ?<!
正则的方法只有两个,test和execcode
一个在字符串中执行查找匹配的RegExp方法,它返回一个数组(未匹配到则返回null)。与字符串的match对应
数组【匹配值,分组,index,input,】
这里注意,exec一次只匹配一个,匹配不到就会null。只有给修饰符g才能往下继续匹配(使用while)
var myRe = new RegExp("d(b+)d", "g"); var myArray = myRe.exec("cdbbdbsbz"); console.log(myArray) //["dbbd", "bb", index: 1, input: "cdbbdbsbz", groups: undefined] --------------------------------------------------------------------- var regex1 = RegExp('foo*','g'); var str1 = 'table football, foosball'; var array1; while ((array1 = regex1.exec(str1)) !== null) { console.log(`Found ${array1[0]}. Next starts at ${regex1.lastIndex}.`); // expected output: "Found foo. Next starts at 9." // expected output: "Found foo. Next starts at 19." }
一个在字符串中测试是否匹配的RegExp方法,它返回true或false。 与字符串的search对应
相似test,exec 可是全局调用match相对exec功能弱了一些,返回的数组元素没有index或者input了
很是有用的一个方法,用来按规则分解字符串造成数组
'a1b2c3d4'.split(/\d/g) // ['a','b','c','d']
很是很是有用的一个方法,全局匹配下因为能自动不断匹配,很是方便。注意若是参数是字符串会隐式转换为
'a1b1'.replace('1','x') // axb1 为何会只替换一次呢,由于这里会给你隐式的转换为正则表达式 'a1b1'.replace(/1/g,'x') // axbx 'a1b1'.replace(/\d/g,function(match){ //匹配字符串,分组(没有则没有该参数),index,原字符 return ~~match + 1 }) // a2b2