正则表达式是用于匹配字符串中字符组合的模式。在JavaScript中,正则表达式也是对象。这些模式用于RegExp的exec和test方法,以及String的match、matchAll、replace、search和split方法。正则表达式的目的是匹配一个模式,一个字符串或一个位置。正则表达式是一种匹配模式,可以是字符串也可以是位置。正则表达式是一种匹配模式,可以是字符串也可以是位置。正则创建方法一:字面量创建constreg=//方法二:构造函数constreg=newRegExp()补充:字面量是常用的。字面量创建和构造函数创建是有区别的//eg:constnum=12.34//literalconstreg=/\d+.\d+///constructorconstreg=newRegExp('\d+.\d+')regare一样,但它们的意思是一样的吗?而不是先看一段代码:console.log('\')//errorJavascript:unterminatedstringliteralconsole.log('\d')//dhere\在解析JS时有特殊含义。所以上面构造方法的创建:constreg=newRegExp('\d+.\d+')//d+.d+匹配字符d//需要转义constreg=newRegExp('\d+\.\d+')这种写法比较麻烦,所以推荐使用直面的写法。正则原子原子是正则表达式最基本的单位,每个模式至少包含一个原子。原子分为可见原子和不可见原子。可见原子:Unicode码表中键盘输入时肉眼可见的字符。不可见原子:Unicode码表中,键盘输入的肉眼不可见的字符,如空格、制表符。通用字符类型:\d匹配0-9[0-9]中的任意数字\D匹配数字以外的任意字符[^0-9]\w匹配数字、字母和下划线[a-zA-Z0-9]\W除字母数字和下划线外的任何字符[^a-zA-Z0-9]\s匹配任何空白字符\S匹配除空白字符外的任何字符[^\n\f\r\t\v]\f formfeedcharacter;\n linefeedcharacter;\r carriagereturncharacter;\t tabcharacter;\v verticaltabcharacter;regularspecialThecharacterstart(^)andend($))用于限制比赛的开始和结束。constreg=/abc///abcaabcabcabc全部匹配成功constreg=/^abc$///只能转义字符(\)\无论是正则还是在其他地方都有特殊的含义。正则表达式中有许多有意义的符号。如果要匹配,都需要转义\()[]^$*+?这些符号有它们自己的含义。下面将介绍conststr='()[]^$*+?'//thisisastringconstreg=/\(\)\[\]\^\$\*\+\?///大量使用escapeor(|)左右两边看成一个完整的,只有其中一个是满意的。constreg=/abc|acc///匹配abc或acc点元字符(.)匹配除\n之外的任何单个字符。letstr=`jameskobe`console.log(str.match(/.+/))//'james'.基本上什么都配。那么matchall怎么写呢?//匹配所有constreg=/[\d\D]+/constreg=/[\s\S]+/constreg=/.+/s//s模式正则量词(*+?){m,n}:匹配m到n个字符,都是数字,也可以写成{m,}:mtounlimitedconstreg=/d{2,4}///匹配d的个数为2到4*:0到无穷大等同于{0,}constreg=/d*/+:1到无穷大等同于{1,}constreg=/d+/?:1or0constreg=/d?/注意:*+?{m,n}都是贪心模式,下面会介绍。原子表([])[]满足其中一项内容constreg=/[abc]////abcab都满足区间匹配[0-9]//匹配0-9的个数[a-z]//匹配a-zLowercaseletters[A-Z]//匹配A-Z的大写字母并反转[^abc]//匹配除abc以外的字符这里虽然^和起始字符一样,但是意思不一样。这里^用在[]中。不解析字符[.()+]//在原子表中都是简单的字符原子组(())()不同于原子表[],()会将里面的内容看成一个整体.constdom=`
copyer
`constreg=/^
[\s\S]*$/i//相当于constreg1=/^
[\s\S]*\1>$/([1-6])整体,只是为了匹配h1~中第一条规则,h6的标签在匹配开始标签和结束标签的时候会写两次([1-6]),这个好像比较麻烦1.组名组名:就是针对上面重复写的题。从左到右,一个一个找到原子团(),用\num作为第一个;例如:([1-6])是原子组中的第二个,则用\2向上。简单记忆:只要判断是原子组,就计数(从左到右数2,嵌套组//匹配urlconsturl='http://www.baidu.com'constreg=/^https?://[\w]+.[\w]+.(com|cn)$/console.log(url.match(reg))匹配方法也会总结[0:”http://www.baidu.com"1:"com"groups:undefinedindex:0input:"http://www.baidu.com"]数组中第一个为匹配的字符串如果使用原子组,匹配的string结果会依次放在第一个后面3.com组不是从非录音组中抽取出来的吗?不想录音怎么办?constreg=/^https?://[\w]+.[\w]+.(?:com|cn)$/在原子组中:使用?:不会记录在组中(?:com|cn)?:放在第4组实际使用场景给一个dom节点字符串,获取里面的内容letstr='copyer
'constreg=/(.*)/console.log(str.match(reg)[2])使用三个原子组d上面:([1-6])(.*)([1-6])全部压入数组,内容为第二原子组。因此,我们去掉标记as2就可以得到内容。正则贪心模式就在上面了,我们知道正则量词(*+?)的基本使用,但是它们还有一个特点:什么是贪心?conststr='aaaaaa'constreg=/a+/console.log(str.match(reg))//只要aaaaaa在条件范围内,多少就可以匹配到多少,贪心思想那么如何停止贪心?添加?conststr='aaaaaa'constreg=/a+?/console.log(str.match(reg))//a*?+???{m,n}?相似的这个正则属性组合lastIndexlastIndex从字面上理解:最后一个索引值实际上是正则表达式开始下一次搜索的索引位置。lastIndex第一次始终为0。当第一次搜索结束时,lastIndex的值会被设置为匹配字符串的最后一个字符的索引位置加1conststr='aaa_aa_aaaa'constreg_g=/a+/gconsole.log(reg_g.lastIndex)//0默认值console.log(reg_g.exec(str))//aaaconsole.log(reg_g.lastIndex)//3最后匹配的aaa下标值为2,上面加1一次,所以是3console.log(reg_g.exec(str))//因此本次匹配从下标为3的位置开始,如果没有匹配,lastIndex将被重置为0。重要提示:没有带有标志g且不代表glob模式的RegExp对象不能使用lastIndex属性。后来好像也支持y修饰符了。lastIndex是一个可读可写的属性。正则修饰符smodifier/s表示将字符串匹配为单行。constdom=`123
`;constreg=/.+/s;console.log(dom.match(reg));s模式,字符串将通过查看一行来解析[0:"\n123
\n"groups:undefinedindex:0input:"\n123
\n"]\ni修饰符正则区分大小写是的,如果它处于i模式,不区分大小写。g修饰符全局匹配。一般情况下,如果没有量词,如果匹配到一个,则不会继续匹配。如果加了\g,就会一直匹配,满足条件。y修饰符y修饰符的作用类似于g修饰符。也是全局匹配,下一次匹配从上一次匹配成功的下一个位置开始。区别:g修饰符只需要匹配剩余的位置,而y修饰符保证必须从剩余的第一个位置开始匹配这里理解y修饰符和g修饰符需要理解上面的lastIndex正则属性实例:conststr='aaa_aa_aaaa'constreg_g=/a+/gconstreg_y=/a+/yconsole.log('第一次')console.log(reg_g.lastIndex)//0console.log(reg_y.lastIndex)//0console.log(reg_g.exec(str))//aaaconsole.log(reg_y.exec(str))//aaaconsole.log('第二次')console.log(reg_g.lastIndex)//3console.log(reg_y.lastIndex)//3console.log(reg_g.exec(str))//aaconsole.log(reg_y.exec(str))//nullconsole.log('第三次')console.log(reg_g.lastIndex)//6console.log(reg_y.lastIndex)//0console.log(reg_g.exec(str))//aaaaconsole.log(reg_y.exec(str))//aaa第一次,y修饰符和g修饰符同理,lastIndex已经从0变成了3,第二次,g修饰符可以继续match剩下的字符aa,所以lastIndex从3变成了6,但是y修饰符需要满足剩余字符的第一个,很明显第二次剩余的字符不满足,所以匹配值为null,第三次lastIndex也从0重置为0,y修饰符重新开始匹配。u修饰正则方法字符串方法match()语法:str.match(regexp)参数:一个正则表达式对象。如果传递了一个非regex对象,它会使用newRegExp(obj)隐式转换为RegExp。如果你直接使用match()方法而不给任何参数,你将得到一个包含空字符串的数组:[""]。返回值:如果有g修饰符,则返回所有匹配信息,不返回捕获值。如果没有g修饰符,将返回一个完整且相关的捕获值。示例://情况1:存在g修饰符conststr="copyer";console.log(str.match(/c/g));//['c']//情况2:g修饰符不存在conststr="copyer";console.log(str.match(/c/));//完整信息[0:"c"//捕获值组:未定义索引:0输入:“copyer”]matchAll()语法:str.matchAll(regexp)参数:正则表达式对象。如果传递的参数不是正则表达式对象,它将使用newRegExp(obj)隐式转换为RegExp。RegExp必须是设置全局模式g的形式,否则会抛出异常TypeError。返回值:一个迭代器实例:conststr="abaca";constmatches=str.matchAll(/a/g)//必须是全局模式//返回值是迭代器对象,使用for...of遍历for(letkeyofmatches){console.log(key)}//['a',index:0,input:'abaca',groups:undefined]//['a',index:2,input:'abaca',groups:undefined]//['a',index:4,input:'abaca',groups:undefined]这是获取所有捕获值的方法。但在matchAll()出现之前,同样的目的是通过正则方法exec()来实现的。下面会介绍。replace()语法:str.replace(regexp|substr,newSubStr|function)参数:regexp(pattern)RegExp对象或其文字值。正则表达式匹配的内容将被第二个参数的返回值替换。substr(pattern)将被newSubStr替换的字符串。它被视为一个完整的字符串,而不是一个正则表达式。只有第一次出现的将被替换。newSubStr(replacement)用于替换原字符串中第一个参数的匹配部分。可以在此字符串中插入一些特殊的变量名。function(replacement)用于创建新子串的函数,该函数的返回值将替换第一个参数匹配的结果。返回值:不改变原字符串,返回一个新的字符串实例://情况一:参数为字符串:将参数视为一个整体,替换第一个匹配到的项conststr="abaca";constnewStr=str.replace('a','f')console.log(newStr)//fbaca//情况二:参数为正则:匹配到的字符被新字符串替换conststr="abaca";constnewStr=str.replace(/a/g,'f')console.log(newStr)//fbfcf//情况三:第二个参数是一个函数,返回的字符串用来替换conststr="abaca";constnewStr=str.replace(/a/g,()=>{return'$#'})console.log(newStr)当然这个函数没有这么简单,还有其他用途.search()语法:str.search(regexp)参数:一个正则表达式(regularexpression)对象。如果传入一个非正则表达式对象regexp,它会使用newRegExp(regexp)隐式转换为正则表达式对象。返回值:如果匹配成功,则search()返回正则表达式在字符串中第一次出现的索引;否则,返回-1。例子:conststr="abaca";console.log(str.search(/[b]/g))//1console.log(str.search(/[d]/g))//-1split()语法:str.split([separator[,limit]])参数:separator指定一个字符串,表示每个拆分应该发生的点。分隔符可以是字符串或正则表达式。如果纯文本分隔符包含多个字符,则必须找到整个字符串来表示分割点。如果分隔符被省略或出现在str中,则返回的数组包含一个由整个字符串组成的元素。如果分隔符是空字符串,则返回str的原始字符串中每个字符的数组。limit是一个整数,用于限制返回的分割数。提供此参数时,split方法会在每次出现指定分隔符时拆分字符串,但会在将限制条目放入数组时停止。如果在达到指定的限制之前到达字符串的末尾,它可能仍然包含少于限制的条目。新数组中不会返回剩余的文本。返回值:返回由分隔符的外观分隔的源字符串的Array实例:conststr="abaca";console.log(str.split('c'))//['aba','a']console.log(str.split('@'))//['abaca']console.log(str.split(''))//['a','b','a','c','a']console.log(str.split('a'))//['','b','c','']console.log(str.split('',3))//['a','b','a']描述:当找到分隔符时,将其从字符串中移除并返回一个子字符串数组。如果没有找到或省略定界符,则该数组包含一个由整个字符串组成的元素。如果delimiter为空字符串,则将str转换为字符数组。如果定界符出现在字符串的开头和/或结尾,则分别以空字符串开始和结束,结尾或两者。注意:如果定界符是包含捕获括号的正则表达式,每次定界符匹配时,捕获括号的结果(包括任何未定义的结果)将被连接到输出数组中。但是,并非所有浏览器都支持此功能。conststr="蕉麻";安慰。log(str.split(/(a)/))//['','a','b','a','c','a','']常规方法test()语法:regexObj.test(str)参数:str用于匹配正则表达式字符串返回值:若正则表达式匹配指定字符串,则返回true;否则,假的。示例:letstr='helloworld!';让结果=/^hello/.test(str);控制台日志(结果);//trueexec()语法:regexObj.exec(str)参数:str必须匹配正则表达式的字符串。返回值:如果匹配成功,则exec()方法返回一个数组(包括附加属性index和input),并更新正则表达式对象的lastIndex属性。完全匹配的文本将是返回数组中的第一项。从第二项开始,后面的每一项对应正则表达式中捕获括号中匹配成功的文本。如果匹配失败,则exec()方法返回null并将lastIndex重置为0。例子:conststr="abaca";constreg=/a/gconsole.log(reg.lastIndex)//0console.log(reg.exec(str))//['a',index:0,input:'abaca',groups:undefined]console.log(reg.lastIndex)//1lastIndex将被更新。获取所有匹配信息:letstr="abaca";letreg=/a/g;letresult;while((result=reg.exec(str))!=null){console.log(result)}//['a',index:0,input:'abaca',groups:undefined]//['a',index:2,input:'abaca',groups:undefined]//['a',index:4,input:'abaca',groups:undefined]错误的写法:letstr="abaca";letreg=/a/g;letresult;while(reg.exec(str)!==null){console.log(result)}警告:不要将正则表达式文字(或RegExp构造函数)放在while条件表达式中。由于lastIndex的属性每次迭代都会被重置,如果匹配上,就会造成死循环。并且一定要使用'g'标志进行全局匹配,否则也会造成死循环。正则断言是先断言(?=)后面的内容满足前面的条件例:str='我有一支铅笔,我有一支笔',把铅笔前面的那个换成两个letstr="IThere是铅笔,我有钢笔”;constreg=/one(?=pencil)/gconstnewStr=str.replace(reg,'two')console.log(newStr)//我有两支铅笔,我有一支笔理解:就把它当作一个条件,后面的内容是否等于'匹配内容'。上面的例子中,如果要把一个改成两个,全局搜索的话,会找到两个,我们只需要匹配铅笔的那个,所以判断条件等于(?=)铅笔否定前瞻断言(?!=)后面的内容不满足前面的条件例:letstr="Ihaveapencil,Ihaveapen";constreg=/a(?!pen)/gconstnewStr=str.replace(reg,'two')console.log(newStr)//我有两支铅笔,我有一支钢笔,可以反过来,可以positive,然后断言(?<=)前面的内容满足下面的条件。例子:letstr="我有一个大爸爸和一个二爸爸";constreg=/(?<=big)dad/gconstnewStr=str.replace(reg,'Grandpa')console.log(newStr)//我有一个大爸爸,第二个父亲改变了大父亲的父亲并且第二个父亲对父亲(只是一个例子,其他方法更简单)否定之后,做一个断言(?<!)前面的内容不满足后面的条件例子:letstr="Ihaveabigdaddyandaseconddaddy";constreg=/(?