RegExp()在es5中,RegExp构造函数参数有两种情况1,字符串2,正则表达式//第一种情况letregex=newRegExp('abc','i')//第二种caseletregex2=/abc/i这两种情况是等价的lets='abc'regex.test(s)==regex2.test(s);//es5中的true这两个方法不能混用。如果第一个参数是正则,第二个是修改,会报错letregex3=newRegExp(/abc/,'i')//报错es6改变了这个行为,如果第一个是正则,第二个参数可以使用修饰符,返回的正则表达式会忽略原来的正则表达式修饰符,只使用新指定的修饰符。letregex4=newRegExp(/abc/ig,'i')这里,第二个参数i会覆盖掉原来的正则修饰符ig,最后的结果是正则表达式中加了/abc/iu修饰符es6u修饰符加了,表示为==Unicode模式==,用于处理大于\uFFFF/^\uD83D/u.test('\uD83D\uDC2A')的Unicode字符;//false在这里添加你。于是变成es6支持,把\uD83D\uDC2A翻译成字符,不匹配\uD83D,所以返回false/^\uD83D/.test('\uD83D\uDC2A');//true这里没有你。es5支持,无法识别4字节的UTF-16编码。它会将\uD83D\uDC2A识别为两个字符,比较时里面的字符会匹配,所以会返回true。正则表达式中的点字符表示除换行符外的任意单个字符,但对于码位大于0xFFFF的字符不能被点串识别,必须在前面加上u修饰符letz='正'/^.$/.test(z);//真/^.$/u.test(z);//trueUnicode字符表示es6增加了大括号表示unicode字符,必须在正则表达式中用u修饰符识别,否则会被解释为量词,量词不能识别大于0xFFFF的unicode字符。/\u{61}/.test('a');//false/\u{61}/u.test('a');//truei修饰符i修饰符不区分大小写,对于值大于0xFFFF的unicode修饰符后面需要跟u/[a-z]/i.test('\u212A');//假/[a-z]/iu.test('\u212A');//truey修饰符y修饰符表示sticky修饰符是正则匹配,g是全局匹配,没有位置限制。y在正则匹配中有位置限制,必须从==上一个匹配后的下一个字符串的第一位开始匹配。==leta='aaa-aa-a'letr=/a+/yletr2=/a+/g//首先匹配r.exec(a);//aaar2.exec(a);//aaa//第二个匹配r.exec(a);//nullr2.exec(a);//aay是胶水,最后一个匹配后的下一个字符串的第一个字符,第一个字符是:-无法匹配,解决方法:其实只需要修改正则表达式,保证每次都匹配就可以了/a+-/yg是全局匹配,没有位置限制regExp.prototype.sticky检查是否设置了y修饰符leta1=/heelo//abcconsole.log(rul.flags);//igs修饰符:在dotAll模式的正则表达式中,点(.)是一个特殊字符,代表任意字符,但有两个例外。第一种:四字节UTF-16字符,这个用u修饰符来解决第二种:行终止符,用s修饰符来解决行终止符,即这个字符代表一行的结束,下面四个字符属于“行结束符”U+000A换行符(\n)U+000D回车符(\r)U+2028行分隔符(lineseparator)U+2029段落分隔符(paragraphseparator)letf=/foo.bar/.test('foo\nbar')console.log(f);//假//因为.不匹配\n,正则表达式返回false//解决方法:s修饰符/*使用s修饰符使。匹配任何单个字符*/letf2=/foo.bar/s.test('foo\nbar')console.log(f2);//trues修饰符的模式称为dotAll模式,dot代表所有字符。因此正则表达式也引入了dotAll模式,检查表达式是否开启了dotAll模式。让f3=/foo.bar/sconsole.log(f3.dotAll);//true//启动dotAll模式lookaheadassertion和lookaheadassertionlookaheadassertion表示x在y之前匹配语法:/x(?=y)/x在y符号之前匹配letlook='100%EasternUndefeated'/\d+(?=%)/.exec(看);//100//百分号前的数字Onlymatchletlook2='100!《东方不败》console.log(/\d+(?=%)/.exec(look2));//null%之前的数字不匹配。语法:/(?<=y)x/描述:?后跟<=条件yletlook3='东不败$100西求败'/(?<=\$)\d+/.exec(look3);//100表示??匹配\$之后的字符注意:前评估和后评估的条件是返回结果中不包含的命名组匹配正则表达式使用括??号进行组匹配,每组括号表示匹配,可以从组中提取匹配结果letrul=/(\d{4})-(\d{2})-(\d{2})/letr=rul.exec('2022-12-13')console.log(r[1]);//2022console.log(r[2]);//12console.log(r[3]);//13个结果虽然可以从组中提取,但是是通过下标提取的。如果组的顺序发生变化,则需要相应地更改下标。其实也不方便。为此,es2018引入了“命名组匹配”。可以给组别名,通过别名提取结果语法:(?regular)letrul2=/(?\d{4})-(?\d{2})-(?\d{2})/letr2=rul2.exec('2022-12-13')console.log(r2.groups.year);//2022console.log(r2.groups.month);//12console.log(r2.groups.day);//13控制台。日志(r2.groups.minute);//undefined如果没有匹配到,则对象属性为undefined解构赋值和替换通过上面的namedgroup匹配,给group起别名后,在regulargroups中,匹配的属性其实是一个对象,可以直接赋值给一个通过解构赋值从匹配结果中获取变量。可以匹配任意字符,查找单个字符,换行符和行尾字符除外。n*匹配任何包含零个或多个n的字符串。解构:let{groups:{hours,minute}}=/^(?.*):(?.*)/.exec('12:49')console.log(hours,minute);//1249//当使用解构赋值提取替换字符串并替换时,在不影响原正则表达式的情况下,使用$替换匹配的字符串位置letrul4=/(?\d{4})-(?\d{2})-(?\d{2})/uconsole.log('2022-12-13'.replace(rul4,'$/$<月>/$<年>'));//13-12-2022console.log(rul4);///(?\d{4})-(?\d{2})-(?\d{2})/ureplace()第二个参数可以是一个函数letdata='2022-12-13'.replace(rul4,(matched,params1,param2,params3,position,sources,groups)=>{让{day,month,year}=groups;return`${day}/${月}/${年}`})console.log(数据);//13-12-2022description:matched//'2022-12-13'匹配结果params1//第一组匹配2022param2//第一组匹配12params3//第一组匹配13position//匹配起始位置0sources//原始字符串2022-12-13groups//由命名组组成的对象{年,月,日}引用如果想引用正则表达式内部的“命名组匹配”,可以使用\k<组名>的方式写作letstr=/^(?[a-z]+)!\k$/str.test('abc!abc');//true指命名匹配,前后均为abc,前后字符一致str.test('abc!ab');//false指的是命名匹配,前后字符不匹配,但是第二个少了一个c,可以这样理解。引用就是把之前定义好的group拿过来重用。编号引用首先需要明确分组的概念,即regular()中的内容是一个分组,里面的内容是作为一个整体引用的。如果组后面带一个\号,表示匹配哪个组letstr2=/^(\d{2})([a-z]+)\1$/console.log(str2.test('11abcd'));//falseconsole.log(str2.test('11aa11'));//true第一个输出:问题是结尾是英文,这里结尾用\数字,1表示匹配第一组,第一个A组必须是2个数字,这里结尾是英文,所以返回false第二次输出:true,其实此时的正则是/^(\d{2})([a-z]+)(\d{2})$/,\1指的是第一组命名匹配引用和数值引用可以同时使用设str3=/^(?[a-z]+)-(\d{2})-\k-\2$/str3.test('a-11-a-11');//truestr3.test('a-11-a-aa');//false第一个输出:这里使用reference和numberreference的第二个输出:false,end被number引用后,应该是一个number\d{2}d修饰符:正则匹配索引es2022加了一个d修饰符,可以在exec()和match()的返回结果中添加indices属性,在其上可以得到匹配的开始位置和结束位置,下标从0开始lettext='abcdefg'lette=/bc/dletresult=te.exec(text)result.index;//1获取bc匹配的起始位置,下标为1result.indices;//[1,3]获取下一个字符在bc匹配开始和结束的位置==很重要!!!这里需要注意的是,匹配字符串的起始位置是字符串的第一个值,匹配的结束位置不在返回结果中。正确的说,匹配的结束位置就是匹配字符串末尾的下一个位置,如果不理解这句话,后面的内容就很难理解了==如果正则模式中包含组匹配,那么数组对应indices属性会包含多个成员,并提供每个组的起始位置和结束位置lettext2='abccdef'lette2=/bc+(de)/dletresult2=te2.exec(text2)console.log(result2.指数);//[1,6][4,6]这里的匹配不是单个匹配,而是一个整体。最外层的bc不参与单独匹配,而是放在整个bcde中,所以第一个数组打印1,6,b的下标为1,e下一个字符的下标为6`组会单独匹配,d的下标为4,e的下一个字符的下标为6,多组匹配,如下标准lettext3='abccdefgh'lette3=/bc+(de(fg))/dletresult3=te3.exec(text3)result3.indices;//[1,8][4,8][6,8]匹配顺序为:bcdefg,defg,fg,对应打印结果[1,8][4,8][6,8]如果正则expression包含命名匹配,则indices.groups的属性将是一个对象,可以从该对象获取命名组匹配的开始位置和结束位置lettext4='abcdefgh'lette4=/bc+(?de)/d//命名组letresult4=te4.exec(text4)result4.indices;//[1,5][3,5]result4.indices.groups;//{word:[3,5]}如果没有匹配,则打印undefinedString.prototype.matchAll()matchAll()可以一次取出所有匹配返回一个迭代器而不是数组letstrings='test1test2test3';letregex=/t(e)(st(\d?))/g;for(letmatchofstrings.matchAll(regex)){console.log(match);//将所有匹配项返回给数组方法一[...strings.matchAll(regex)];//返回所有匹配,结果是数组到数组方法二Array.from(strings.matchAll(regex));//返回所有匹配,结果为数组案例源码:https://gitee.com/wang_fan_w/es6-science-institute如果您觉得本文对您有帮助,请点亮星星