我们都知道js内置类String提供了一个replace方法,可以把指定字符串替换为另一个字符串,他的基础用法如下:



1 var str="hello world";
2 
3 var str=str.replace("world","js");
4 
5 console.log(str);//输出"hello js"



replace方法第一个参数还可以是一个正则表达式:



1 var str="hello world";
2 
3 var str=str.replace(/world/,"js");
4 
5 console.log(str);//同样输出"hello js"



今天我要说的重点是他的第二个参数,第二个参数其实是一个函数,只不过我们通常采用了简写模式,简单的写了一个返回值,实际上他的原理是这样的:



1 var str="hello world";
2 
3 var str=str.replace(/world/,function(){
4     return "js";
5 });
6 
7 console.log(str);



那这个函数是怎么实现替换的呢?我们先来看看这个匿名函数的参数(谷歌浏览器打印arguments):

openresty 正则 正则表达式replace 的用法_正则表达式

可以看到控制台输出了三关键个参数,解释一下,第一个参数是replace方法第一个参数(也就是/world/)匹配到的内容,第二个参数是匹配内容出现的位置索引,第三个参数就是原始字符串

如果你传入的第一个参数是字符串,replace方法默认替换一次匹配到的内容:如下:



1 var str="hello world world";//把world变成js
2 
3 str=str.replace("world","js");
4 console.log(str);//输出的是"hello js wolrd"



我们想要的结果是两个world都变成js,显然这种办法不能满足我们的需求。这时第一个参数就只能传入一个正则表达式了。



1 var str="hello world world";//把world变成js
2 
3 str=str.replace(/world/g,"js");
4 console.log(str);//输出"heloo js js"



 当我们传入正则表达式,并且加上全局匹配模式/g,我们再来看看控制台输出,打印两次:

openresty 正则 正则表达式replace 的用法_openresty 正则_02

可以发现实际上匹配到几次,函数就执行了几次,并且返回匹配到的结果与索引。 

对于一般的需求,我们只需要传递一个字符串当作第二个参数即可,但是当我们遇到复杂的情况时,就要使用函数去解决了,比如如下场景:



1 var str="hello world world";//把字符串转换成大写
2 
3 str=str.replace(/world/g,function(){
4     return arguments[0].toUpperCase();
5 });
6 
7 console.log(str);



 读到这里,笔者可以提示你一下,实际上大部分模板引擎实现原理就是这样,读者可以自己尝试这用这个方法去实现一个简单的模板引擎。笔者这里就不再多说。最后祝大家国庆节快乐,但是也别忘记学习,学无止境,这样才能进步。