字符串的replace
方法是操作字符串的常用方法之一,但这个方法只有当与正则合并使用时,才能体现出它的强大之处。
语法:str.replace(regexp|substr, newsubStr|function);
返回值: 一个部分或全部匹配由替代模式所取代的新的字符串,因为字符串是不可变的原始类型。
基础用法
str.replace(substr, newsubStr);
将字符串的一个子字符串,替换为另一个新的子字符串。比如:
'eabcabcabcabc'.replace('ab','df')//返回'edfcabcabcabc',只替换第一个子串
'abcabcabcabc'.replace(/ab/g,'df')//返回'dfcdfcdfcdfc',由于正则表达式的g,替换掉所有匹配到的`ab`
带正则的用法
其实前面已经带了一个简单的正则,但是这并没有显出如虎添翼的效果。想象一个场景,你想把一个类似于’201706
‘的字符串替换成’2017-06
'的形式,我们可以这样实现:
'201706'.replace(/(\d{4})(\d{2})/,'$1-$2')//'2017-06'
'13299259212'.replace(/(\d{3})(\d{4})(\d{4})/,'$1-$2-$3')
这个地方主要在于正则的捕获,上面的正则表达式,\d{4}
匹配字符串的前四个数字,\d{2}
匹配后两个数字,分别用小括号包起来,放到后边对应的$1,$2
中,这里的$1
和$2
不是字面的意思。而是两个占位符,😄
除了$n这个匹配捕获的占位符外,还有$&, $`,$'这三个占位符: 说个题外话,一分钟前搜了一下,用markdown转义`字符时,最外层用两个 ``将里面的` 包起来就行,看起来像这样`` $` ``
MDN描述如下:
变量名 代表的值 $$ 插入一个 "$"。 $& 插入匹配的子串。 $` 插入当前匹配的子串左边的内容。 $' 插入当前匹配的子串右边的内容。 $n 假如第一个参数是RegExp对象,并且 n 是个小于100的非负整数,那么插入第 n 个括号匹配的字符串。
前面说了n
代表()
里捕获的z
字符串,相当于转义`,下面说说另外的几个占位符
'abc'.replace(/b/,"$`")//aac,b前面是a,所以将b替换成a,得到a(a)c
'abc'.replace(/b/,"$'")//acc,b后面是c,所以将b替换为c,得到a(c)c
'aaabccc'.replace(/b/,"$`$'")//aaaaaacccccc,你懂的
'abcdefg'.replace(/b|c|f/g,'$&O')//abocodefog,这里$&分别代表bcf
'abcdefg'.replace(/(ab)c(de)/g,'$&O')//abcdeofg,这里$&代表abcde
'abcdefg'.replace(/\S{3}/g,'$&O')//abcOdefOg,这里$&代表abc和def
带函数的用法
这里就是将函数作为replace
方法的第二个参数了,可以看作是上面的函数版和加强版
function replacer(match,$1,$2,$3,offset,string){
console.log('$&',match);
console.log('$1',$1);//132
console.log('$2',$2);//9925
console.log('$3',$3);//9212
console.log('开始位置',offset);
console.log('string',string);
return(`${$1}-${$2}-${$3}`);
}
'13299259212'.replace(/(\d{3})(\d{4})(\d{4})/,replacer)
举个例子,将’AbCdEfddd’转换成’ab_cd_efddd’这样的形式,实现如下:
'AbCdEfddd'.replace(/[A-Z]/g, function(match, index, string){
if(index === 0){
return match.toLowerCase()
}
return '_' + match.toLowerCase()
})
可以看出正则的占位符写法更直观也更简便,但函数写法会更自由。