重拾JS正则:别在被正则表达式难住了

483 阅读7分钟

文章的目录

如何创建正则表达式

  • 字面量创建let reg=/a/
  • 构造函数创建new RegExp(variable,'g')

正则表达式的方法之test和exec

  • test()方法
  • exec()方法

字符串的四个方法

  • split()方法
  • search()方法
  • match()方法
  • replace()方法

正则表达式中与字符相关的知识点

  • \d和\D
  • \w和\W
  • \s和\S
  • .点号

正则表达式中与数量相关的知识点

  • {}大括号
  • +加号
  • *星号
  • ?问号

正则表达式中与位置相关的知识点

  • ^
  • $
  • \b和\B

正则表达式中与括号相关的知识点

  • []中括号
  • {}大括号
  • ()圆括号

正则表达式中与字符集合相关的知识点


正则表达式中与匹配模式相关的知识点

  • g、y、m、s、u

正则表达式中与命名分组相关的知识点

  • 零宽断言
  • groups

如何创建正则表达式

字面量创建(重点感受创建方式,各种方法的使用后续会有精讲)

  • 演示案例一:
let str='ababbabbbabbbabb'
//不加全局匹配的话找到匹配项后就会停止查找不会再去查找整个字符串

//重点感受创建方式
let reg=/a/g; //g是全局匹配的意思

//match方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。
let arr=str.match(reg);
console.log(arr) //["a", "a", "a", "a", "a"]
  • 演示案例二:
let str2='11abkja456shdjf123hlfjhabkjd111variable123'; 


//重点感受创建方式
let reg=/\d+/g;


//默认是贪婪匹配,尽可能的去匹配到更多的符合条件的字符串
let arr=str2.match(reg);
console.log(arr) //["11", "456", "123", "111"]
  • 演示案例三:
let str2='11abkja456shdjf123hlfjhabkjd111variable123'; 

//因为在正则表达式里全都当成是字符串不可能是变量
//所以尽管书写let variable='123'和let reg=/variable/
//该正则表达式(这里指reg)里面的内容始终是一个字符串(这里是'variable')
let variable='123';  


//知识点:在正则表达式里全都当成是字符串不可能是变量
//重点感受创建方式
//尽管上方variable是一个变量下面的正则表达式里的内容依旧是一个字符串'variable'
let reg2=/variable/;  //这里不加全局匹配
let arr3=str2.match(reg2);



//感受字符串的match方法在全局匹配和非全局匹配的区别
console.log(arr3) 
//["variable", index: 31, input: "11abkja456shdjf123hlfjhabkjd111variable", groups: undefined]
  • 演示案例四:
let str2='11abkja456shdjf123hlfjhabkjd111variable123';

//重点感受创建方式
let reg=/abk/g  //精确匹配并且加了全局匹配
let arr2=str2.match(reg);


//感受字符串的match方法在全局匹配和非全局匹配的区别
console.log(arr2) //["abk", "abk"]

构造函数创建(重点感受创建方式,各种方法的使用后续会有精讲)

  • 演示案例一:
let str2='11abkja456shdjf123hlfjhabkjd111variable123';


//重点感受创建方式
//知识点:涉及带斜杠的例如\d需要多一个转义字符\
let reg3=new RegExp('\\d+','g')
let arr4=str2.match(reg3);


console.log(arr4) //["11", "456", "123", "111"]
  • 演示案例二:
let str2='11abkja456shdjf123hlfjhabkjd111variable123';


//可以给构造函数的第一个参数传入变量
let variable='123';  
let reg4=new RegExp(variable,'g')


let arr5=str2.match(reg4);
console.log('arr5',arr5)   // ["123", "123"]

正则表达式的方法之test和exec

正则的第一个方法:test() 方法用于检测一个字符串是否匹配某个模式,如果字符串 string 中含有与 RegExpObject 匹配的文本,则返回 true,否则返回 false。

  • 演示案例一:(正则中加了全局匹配)
 let str5='123sakjf546slhdal12345fh564';
 
// \d+的意思是匹配1个到无限多个数字 
let reg5=/\d+/g;  

//从这里我们观察到reg5.lastIndex初始值为0
console.log('经过了0次test方法之后',reg5.lastIndex)  //0


//每使用一次test方法,会相应的去改变reg5.lastIndex的值
console.log(reg5.test(str5)); //true 


//从这里可以观察到reg5.lastIndex的值为3,这是因为第一次test到的是123
console.log('经过了1次test方法之后',reg5.lastIndex)  //3


//第二次test到的是546
console.log(reg5.test(str5)); //true


//从这里可以观察到reg5.lastIndex的值为11
console.log('经过了2次test方法之后',reg5.lastIndex)  //11


//第三次tes到的是12345
console.log(reg5.test(str5)); //true
console.log('经过了三次test方法之后',reg5.lastIndex) //22


//第四次test到的是564
console.log(reg5.test(str5)); //true
console.log('经过了四次test方法之后',reg5.lastIndex) //27



//因为第五次已经到头了所以这次的test的结果为false
console.log(reg5.test(str5)); //false


//因为第五次已经到头了所以这次的reg5.lastIndex会变为0重头开始
console.log('经过了五次test方法之后',reg5.lastIndex) //0



//第六次的test到的是为123
console.log(reg5.test(str5)); //true
console.log('经过了六次test方法之后',reg5.lastIndex) //3

正则的第二个方法:exec() 方法用于检索字符串中的正则表达式的匹配。如果字符串中有匹配的值返回该匹配值,否则返回 null。

  • 演示案例二:(正则中加了全局匹配)
let str5='123sakjf546slhdal12345fh564';
let reg5=/\d+/g;  


 console.log('经过了0次exec方法之后',reg5.lastIndex)  //0
 console.log(reg5.exec(str5))
 console.log('经过了1次exec方法之后',reg5.lastIndex)  //3
 
 

console.log(reg5.exec(str5))
console.log('经过了2次exec方法之后',reg5.lastIndex)  //11


console.log(reg5.exec(str5))
console.log('经过了3次exec方法之后',reg5.lastIndex)  //22


console.log(reg5.exec(str5))
console.log('经过了4次exec方法之后',reg5.lastIndex)  //27



//从null之后lastIndex又变为0,又可以从头检索了
console.log(reg5.exec(str5))  //null
console.log('经过了5次exec方法之后',reg5.lastIndex)  //0      



console.log(reg5.exec(str5)) 

  • 演示案例三:(没有加全局匹配)
//如果没有全局匹配g
//那么不管是test还是exec方法都不会改变正则的lastIndex
//此时的exec方法和test方法就算反复调用也始终是返回的是同一个结果
//因为lastIndex始终是0


let str6='123sakjf546slhdal12345fh564';
let reg7=/\d+/;


console.log('初始的lastIndex',reg7.lastIndex)
var res=reg7.exec(str6);
console.log(res)
console.log('执行了一次exec的lastIndex',reg7.lastIndex)



var res2=reg7.exec(str6);
console.log(res2)
console.log('执行了二次exec的lastIndex',reg7.lastIndex)



console.log(reg7.test(str6));
console.log('执行了二次exec加一次test的lastIndex',reg7.lastIndex)


console.log(reg7.test(str6));
console.log('执行了二次exec加二次test的lastIndex',reg7.lastIndex)

字符串的四个方法

  • split()方法用于把一个字符串分割成字符串数组
  • 演示案例一:
let str='12akdfjl1e224ake5787sdnafj54aa54';
var res=str.split('5');
console.log(res) //["12akdfjl1224ak", "787sdnafj", "4aa", "4"]

//可以利用split()方法来判断某个字符在字符串中出现的次数
console.log(res.length-1)  //3


//特别注意如果分割的值出现在字符串的首尾则会产生一个空字符串

//字符串'4'出现在了str字符串的尾部
var res2=str.split('4')
// console.log(res2) //["12akdfjl122", "ak5787sdnafj5", "aa5", ""]


// \d+的意思是匹配一个或至无限多个数字
// 这里分割的值出现在了首尾
// 所以结果数组的第一位和最后一位都是一个空字符串
var res3=str.split(/\d+/);
console.log(res3) //["", "akdfjl", "ak", "sdnafj", "aa", ""]
  • search()方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。会返还符合正则匹配的第一个的索引值,并且会自动忽略全局匹配(就算有也忽略)
  • 演示案例一:
let str='12akdfjl1e224ake5787sdnafj54aa54';

//自动忽略全局匹配
let reg3=/e/g;


//多次使用search返回值始终一致
console.log(str.search(reg3))  //9
console.log(str.search(reg3))  //9
  • match()方法可在字符串内检索指定的值并返回,或找到一个或多个正则表达式的匹配。
  • replace()方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。如果第1个参数是RegExp, JS会先提取RegExp匹配出的结果,然后第2个参数是替换正则结果的新值。但是如果第2个参数是回调函数,则每匹配到一个结果就会触发回调函数一次,该回调函数的参数分别是
  • 演示案例一:
let str='12akdfjl1e224ake5787sdnafj54aa54';


//将所有符合正则表达式的内容替换为*号
let reg5=/\d/g;

//记住replace不会影响原字符串
//它会返回一个新的被改变的字符串
console.log(str.replace(reg5,'*')) //**akdfjl*e***ake****sdnafj**aa**

 console.log(str)
//12akdfjl1e224ake5787sdnafj54aa54
  • 演示案例二:
let str='1a2b3c4d5e6f7g8h9';


var res5=str.replace(reg5,function(arg,index,input){
    console.log(arg,'每一位匹配到的参数')
    console.log('每一位匹配到的参数的下标',index)
    console.log('匹配的字符串',input)
    //每个匹配都调用该函数,它返回的字符串将作为替换文本使用。
    return '*';
})


console.log(res5) //*a*b*c*d*e*f*g*h*

  • 演示案例三:
var name = 'aaa bbb ccc';


// \b是边界符的意思
// \w是匹配字符数字下划线的意思
//该正则的意思是匹配有边界的(一个或至无限个字母数字下划线)的字符
//开头和结尾可以是当作是边界
//空白字符也可以当作是边界


var uw=name.replace(/\b\w+\b/g, function(word){
	console.log(word) //aaa  bbb ccc
	return word.substring(0,1).toUpperCase()+word.substring(1);}
);

console.log(uw) //Aaa Bbb Ccc

正则表达式中与字符相关的知识点

大写的记忆方式:大是大非

  • \d匹配一个数字
  • \D匹配一个数字
  • 演示案例一:
console.log(/\d/g.test('-1')); //true
console.log(/\D/g.test('-1'));  //true
  • \w :匹配数字、字母、下划线可以相当于[0-9a-zA-Z_]
  • 演示案例二:
let str='@';       //false
//let str='';     //false
//let str='_';    //true


let reg=/\w/g;
console.log(reg.test(str))
  • \W 数字字母下划线可以相当于[^0-9a-zA-Z_]
  • 演示案例三:
let str2='@';
let str3='~';
let reg2=/\W/g;
let reg3=/\W/g;
console.log(reg2.test(str2))  //true
console.log(reg3.test(str3))  //true
  • \s匹配空格
  • 演示案例四:
let str2='abc';
let str3=' ';
let reg2=/\s+/g;
console.log(reg2.test(str3)) //true
console.log(reg2.test(str2)) //false
  • \S 空格
let str2='abc';
let str3=' ';
let reg3=/\S+/g;


console.log(reg3.test(str3))  //false
console.log(reg3.test(str2))  //true
  • .点点匹配除了换行回车(\n)和(\r)即 (\u2028)和(\u2029)的字符
  • 演示案例五:
let str1=`a\nb`;
let str2=`a\rb`;

let str3=`assssssb`
let str4=`asb`

// +号是匹配一次或至多次的意思
let reg=/a.+b/;


console.log(reg.test(str3))  //true
console.log(reg.test(str4))  //true
console.log(reg.test(str1))  //false
console.log(reg.test(str2))  //false

正则表达式中与数量相关的知识点

- {}大括号的值表示的是出现几次到几次。例如{1,2}表示出现一次到两次

let str='abceeeffd';
let reg=/ceeef/g;

//改写为:
let reg1=/ce{3}f/g;

// let reg2=/ce{3,4}f/g; //出现3次到4次
// let reg3=/ce{1,}f/g; //出现1次到无限次
   
   
console.log(reg.test(str)) //true
console.log(reg1.test(str)) //true
  • +加号表示出现一次或至无限多次,用花括号可以{1,}这样来表示
  • 演示案例一:
let str2='my name is lilei';

//表示中间可以出现一个或至多个空格
let reg3=/my\s+name/g


console.log(reg3.test(str2)) //true
  • *星号表示出现0次或至无限多次,用花括号可以{0,}这样来表示
let reg=/\w\d*/;
let str='a120';
console.log(reg.test(str)) true
  • 问号表示出现0次或一次,用花括号可以{0,1}这样来表示
  • 演示案例二:
let str5='1234567898';


//g是全局匹配的意思
let reg4=/\d{2,4}/g


//(贪婪匹配)按照最多位数先来匹配(这里最多是可以匹配4位数)  
let res=str5.match(reg4);


console.log(res,'res') 
//["1234", "5678", "98"]
  • ?问好除了代表{0,1} 还可以进行 惰性匹配只要在花括号后面加上问号即可
let str5='1234567898';

//在花括号后面加上问号
let reg6=/\d{2,4}?/g
let res1=str5.match(reg6);



//会去尽可能匹配最少位数(这里最少是2位)的字符
console.log(res1,'res') 
//["12", "34", "56", "78", "98"] "res"

正则表达式中与位置相关的知识点

  • ^根据位置的不同有不同的含义表达,在中括号[]里面的^表示的意思,在中括号[]外面正则//里面表示以谁为首字符的意思
  • $表示以谁(哪个字符)为末尾的意思
  • 演示案例一:

let str='abedfs'
let reg=/^\w/g;  //以\w开头的首字符
let reg1=/\w$/g; //以\w结尾的最后一个字符


let res=str.replace(reg,'*');
let res1=str.replace(reg1,'*');


console.log(res) //*bedfs
console.log(res1) //abedf*
  • \b是边界的意思,开头结尾都可以称之为边界,非\w的都是边界,空格也是边界。
  • 演示案例二:
let str5='this is book';


let reg5=/is/g
let reg6=/\bis\b/g


let res5=str5.match(reg5)
let res6=str5.match(reg6)


//有两个is因为不需要判断\b
console.log(res5) //["is", "is"]


//字符串的第一个'is'左边‘th’不是边界
console.log(res6) //["is"]
  • 演示案例二:
//非/w的都是边界
let str5='@is is _is';


let reg5=/is/g
let reg6=/\bis\b/g

//有三个'is'不需要考虑其他
let res5=str5.match(reg5)


//第一个‘is’左边有边界@右边有空格(边界)
//第二个‘is’左边和右边都是空格(边界)
//第三个‘is’左边是下划线‘_’,这个不是边界
let res6=str5.match(reg6)



console.log(res5) //["is", "is", "is"]
console.log(res6) //["is", "is"]
  • 演示案例三:
let str5='@is is _isth';


let reg7=/th\b/g
let res7=str5.match(reg7)
console.log(res7) //['th']



let reg8=/\bth\b/g
let res8=str5.match(reg8)
console.log(res8) //null
  • \B是非边界符的意思。
  • 演示案例四:
let str5='this is book';


//匹配一个或至多个\w字符且该字符左边非边界右边有边界
let reg9=/\B\w{1,}\b/g
let res9=str5.match(reg9)
console.log(res9) //["his", "s", "ook"]



let reg10=/\B\w{1,2}\b/g
let res10=str5.match(reg10)
console.log(res10) //["is", "s", "ok"]

正则表达式中与括号相关的知识点

  • []中括号可以表示某个区间内例如[a-zA-Z0-9];可以表示某几个的范围例如[abcd];可以在中括号中进行取非的操作例如[^a];在中括号中的字符不再有特殊的含义例如[\s*]表示空格或者*号。
  • {}大括号和数量有关,一般用来表示匹配的长度。例如 \s{3} 表示匹配三个空格,而\s[1,3]表示匹配一到三个空格。
  • ()圆括号可以用来分组捕获组提取值替换反向引用。具体请看案例:
  • 演示案例一:
let str='ababababfsfsfdfdseseaa'
let reg=/ababab/g
console.log(reg.test(str)) //true


//这里的意思原本是想要匹配‘ab’这两个字符出现了三次的
//可以却变成了匹配'b'字符出现了三次的
let reg1=/ab{3}/g   //产生了歧义
console.log(reg1.test(str)) //false


//改造后我们将‘ab’加上圆括号就可以消除歧义了
let reg2=/(ab){3}/g 
console.log(reg2.test(str)) //true
  • ()圆括号捕获组提取值
  • 演示案例二:
let str5='2020-09-20';

//这里没加全局匹配
let reg5=/\d{4}-\d{2}-\d{2}/


let res=str5.match(reg5)


console.log(res,'res') 
//["2020-09-20", index: 0, input: "2020-09-20", groups: undefined]

  • RegExp.$1RegExp.$2……对应着圆括号出现的顺序
  • 演示案例三:
let str10='1999-09-20';

//这里没加全局匹配但是加上了圆括号来设为捕获组
let reg10=/(\d{4})-(\d{2})-(\d{2})/


let res10=str10.match(reg10)
console.log(res10,'res10') 

console.log(RegExp.$1) //1999
console.log(RegExp.$2) //09
console.log(RegExp.$3) //20

  • 演示案例四:
//如果想要拿到具体的内容呢?
let reg6=/(\d{4})-(\d{2})-(\d{2})/



//会先匹配整个再去匹配捕获组里面的内容
//如果加上全局匹配只会匹配一个
let res1=str5.match(reg6)


console.log(res1,'res1') 
//["2020-09-20", "2020", "09", "20", index: 0, input: "2020-09-20", groups: undefined]



console.log(RegExp.$1) //2020
console.log(RegExp.$2) //09
console.log(RegExp.$3) //20

  • ()圆括号可以用于替换
  • 演示案例五:
//我们想要将st替换为01/02/2020
let st='2020-01-02'; 

//匹配st的正则
let re=/(\d{4})-(\d{2})-(\d{2})/;


//st.replace(re,'21/02/2020');
//通过$1、$2、$3的方式获得捕获组的值
let r=st.replace(re,'$2/$3/$1');


//记住replace的方法返回值才是替换的结果,不会影响原字符串
//成功得到替换的结果
console.log(r,'who') //01/02/2020 who
  • 演示案例六:
let st='2020-01-02'; //替换为01/02/2020
let re=/(\d{4})-(\d{2})-(\d{2})/;


//从第二个参数起便对应着捕获组的内容
let r=st.replace(re,function(arg,year,month,date){
  console.log(arg,'我是arg')
  console.log(year,'我是year')
  console.log(month,'我是month')
  console.log(date,'我是date')


  return month+'/'+ date +'/' + year
})

  • ()反向引用例如(\1)表示反向引用第一个捕获组的内容值
  • 现实需求中我们在页面上需要匹配类名为‘news_container_nav’或者类名为'news-container-nav'CLASS,这里的区别只有连接符的不同,一个是以下划线为连接符,一个是以短横线为连接符。
  • 演示案例七:
//下方的正则表示式可以成功匹配这两种类名
//let className='news_container_nav'
let className='news-container-nav';


//这种方式的正则表达式可以成功匹配两种情况
let rexxx=/\w{4}(-|_)\w{9}(-|_)\w{3}/


let x=rexxx.test(className)
console.log(x,'xx') //true 'xx'
  • 虽然需求看似完成了,但是我们会发现类名为'news-container_nav'的这类情况竟然也能匹配成功这显然不是我们想要的,可不可以出现一种模式,让系统记住我们第一次匹配到的连接符,在匹配到第二个连接符的时候,通过记忆自动的帮我们匹配准确的连接符呢?即能不能把第一个捕获组用的内容传递给第二个捕获组呢?。这时候可以用\n(n可以取值1,2,3,4……)来获得第几个的引用值
  • 演示案例八:
let className='news-container-nav';


//使用了反向引用获得的第一个捕获组的内容值
let rexxx=/\w{4}(-|_)\w{9}(\1)\w{3}/



let x=rexxx.test(className)
console.log(x,'xx') //true 'xx'

正则表达式中与字符集合相关的知识点

  • 演示案例一:
// []  字符集合
let str='My name is LiLei';
let reg=/Li(L|l)ei/g
console.log(reg.test(str)); //true


let reg2=/Li[Ll]ei/g
console.log(reg2.test(str)); //true



//[a-z];  [A-Z];   //只匹配一个
//按照字符的ASYNC编码规定的一段内容(必须是连续的)
let reg4=/[0-9]/g;
console.log(reg4.test(str)) //false


//在字符集合里面的^表示非
let reg5=/[^0-9]/g
console.log(reg5.test(str)) //true


\d可表示为[0-9]
\D可表示为[^0-9]
\w可表示为[a-zA-Z0-9_]
\W可表示为[^a-zA-Z0-9_]

正则表达式中与匹配模式相关的知识点

  • g为全局匹配
  • 演示案例一:
let str='abcd123fdafaklj'
let reg=/\d+/g;
let res=str.match(reg);
console.log(res) //[1,2,3]



let str2='abcABC'
let reg2=/abc/g
console.log(reg2.test(str2)) //true
  • m是多行模式的意思
  • 演示案例二:
let str3=`abc
efg
hij
`

//没加多行模式m
let reg3=/^\w/g;
let res3=str3.replace(reg3,'*');
console.log(res3)


//执行结果为:
*bc
efg
hij
  • 演示案例三:
let str3=`abc
efg
hij
`

//加了多行模式m
let reg3=/^\w/gm;
let res3=str3.replace(reg3,'*');
console.log(res3)

//执行结果为:
*bc
*fg
*ij
  • .点号是除了回车换行、段落结束符和行结束符以外的都匹配,而匹配模式s可以让.点号去匹配的到换行
  • 演示案例四:
let str6=`abcedfg`  //其中的*是{0,}
let reg6=/^a.*g/g
console.log(reg6.test(str6),'ok') //true
  • 演示案例五:
let str7=`abc
edfg` 

////没加上匹配模式 s
let reg7=/^a.*g/g

//因为有换行所以点号匹配失败
console.log(reg7.test(str7),'ok2') //false
  • 演示案例六:
let str7=`abc
edfg` 
let reg7=/^a.*g/gs



//没加上s之前值为false
console.log(reg7.test(str7),'ok2') //true
  • u是匹配unicode编码,{}有两种含义一种是数量词(默认是数量词),还有一种可以表示unicode编码(得加上u)
let str8='a';

//'a'的unicode编码是61
let reg8=/\u{61}/gu


console.log(reg8.test(str8))  //true
  • y是粘性模式的意思。默认匹配的方式是非粘性的。
  • 演示案例七:
let str9='123adfdasg65afads1f54fa5fa';

//匹配一个数字(全局模式)
let reg9=/\d/g;


console.log(reg9.exec(str9))  //1
//会根据lastIndex继续执行
//默认来讲是非粘性模式--匹配的字符不是连续的是没有关系的


console.log(reg9.exec(str9))  //2
console.log(reg9.exec(str9))  //3
console.log(reg9.exec(str9)) //6
console.log(reg9.exec(str9)) //5  继续往下

  • 演示案例八:(加上了粘性模式y)
let str10='123adfdasg65afads1f54fa5fa';
let reg10=/\d/gy;



console.log(reg10.exec(str10)) //1
console.log(reg10.exec(str10)) //2
console.log(reg10.exec(str10)) //3
//加上了粘性模式后在这里如果匹配到的不是连续的(数字)字符
//则会把lastIndex重新设为0(不在继续搜索下去了)
console.log(reg10.exec(str10)) //null
console.log(reg10.exec(str10)) //1 //又从头开始
console.log(reg10.exec(str10)) //2
console.log(reg10.exec(str10)) //3
console.log(reg10.exec(str10)) //null
console.log(reg10.exec(str10)) //1 //又从头开始

正则表达式中与命名分组相关的知识点

  • 演示案例一:
let str='2020-01-06';
let reg=/\d{4}-\d{2}-\d{2}/;

//["2020-01-06", index: 0, input: "2020-01-06", groups: undefined]
//注意观察groups是undefined  这个是自定义分组的名称
console.log(str.match(reg))

  • 演示案例二:
let str2='2020-01-06';
let reg2=/(\d{4})-(\d{2})-(\d{2})/;


//["2020-01-06", "2020", "01", "06", index: 0, input: "2020-01-06", groups: undefined]
//注意观察groups是undefined 
console.log(str2.match(reg2))

  • 演示案例三:
let str3='2020-01-06';

//命名分组出现了!!!
let reg3=/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;


console.log(str3.match(reg3))

  • 零宽断言
  • 正向零宽断言:匹配后面
  • 演示案例四:需求是我们要处理一串字符‘iphone3iphone4iphone4iphonenumber’,要将其中的‘iphone’替换为‘苹果’,而且我们并不想替换掉数字
let str4=`iphone3iphone4iphone4iphonenumber`;
let reg4=/iphone\d/g;  //替换掉了iphone和数字


console.log(str4.replace(reg4,'苹果'))
//苹果苹果苹果number
  • 演示案例五:(使用了正向肯定零宽断言)
let str5=`iphone3iphone4iphone4iphonenumber`;
let reg5=/iphone(?=\d)/g;  



console.log(str5.replace(reg5,'苹果'))
苹果3苹果4苹果4iphonenumber
  • 演示案例六:(使用了正向否定零宽断言)
let str6=`iphone3iphone4iphone4iphonenumber`;


let reg6=/iphone(?!\d)/g; 



console.log(str6.replace(reg6,'苹果'))
//iphone3iphone4iphone4苹果number
  • 负向零宽断言:匹配前面
  • 演示案例七:需求是我们要处理一串字符‘10px20px30px40pxipx’我们的想法是我们匹配的时候需要替换掉数字例如10,但是我们替换的时候不希望把‘px’也一同替换掉。
let str='10px20px30px40pxipx';


let reg=/\d+px/g



console.log(str.replace(reg,'像素')
//像素像素像素像素ipx
  • 演示案例八:(使用了负向肯定零宽断言)

let str1='10px20px30px40pxipx';


let reg1=/(?<=\d+)px/g



console.log(str1.replace(reg1,'像素'))
//10像素20像素30像素40像素ipx
  • 演示案例九:(使用了负向否定零宽断言)
let reg2=/(?<!\d+)px/g



let str2='10px20px30px40pxipx';


console.log(str2.replace(reg2,'像素'));
//10px20px30px40pxi像素