关于js中字符串replace方法的第二参数为function时,参数的顺序问题分析

来源:互联网 发布:jmeter 安装部署 mac 编辑:程序博客网 时间:2024/05/21 14:00
最近在研究NODEjs,在看leo老师的教程的时候看到这种js的高级用法,相信很多人也和我又同感,这种用法中,调用函数的参数顺序和正则表达式中分组圆括号的顺序有何种联系呢?下面我们一起探究一下。
先看一个简单的例子:

var reg = /\/((\d+)(\w+))/g;     //匹配斜杠后面跟随多个数字和单词的情况
var s = '/23w';
s = s.replace(reg,function(){
  for(var i=0;i<arguments.length;i++){
     console.log('(arg' + i + ')' + arguments[i]);
  }
  return 'x';
});
console.log(s);
运行结果:
D:\nodejs>node reg.js
(arg0)/23w
(arg1)23w
(arg2)23
(arg3)w
(arg4)0
(arg5)/23w
x
当正则表达式增加一个'|'匹配时,比如:
var reg = /\/((\d+)(\w+))|\/(\w+)/g;
此时运行的结果为:
D:\nodejs>node reg.js
(arg0)/23w
(arg1)23w
(arg2)23
(arg3)w
(arg4)undefined
(arg5)0
(arg6)/23w
x
关于参数的顺序问题:
从以上测试的结果可以看到:
arg0:整个匹配的结果,这里是\/((\d+)(\w+))|\/(\w+)
arg1:最外层括号的匹配结果,这里是23w,也就是((\d+)(\w+))的匹配结果
arg2:内层匹配结果中从左至右第一个匹配结果,这里是23,也就是(\d+)的匹配结果
arg3:内层匹配结果中从左至右第二个匹配结果,这里是w,也就是(\w+)的匹配结果
arg4:加入'|'匹配后面的括号也要作为参数,这里是(\w+),但没有匹配,所以为undefined
arg5:目标字符串和正则表达式中第一次匹配的索引,这里是0
arg6:目标字符串

再来看一个复杂的例子:(这个例子是leo老师教程中的例子,leo老师看到了别生气大笑
// 函数的功能是将一个形如"/article/:id/*/:name"的目标字符串中的":xxx"和"*"替换为“(.*)”
function pathRegexp (routeStr){
     routeStr = routeStr.replace(/\?(.*)$/,'')
                        .replace(/((\*{1}(?=\/))|(\*{1}(?=$)))/g,"(.*)")
                        .replace(/((:(.*?(?=\/)))|(:(.*(?=$))))/g,function(){
                        
                          for(var i=0;i<arguments.length;i++){
                             console.log('(arg' + i + ')' + arguments[i]);
                          }
                        
                          return '(.*)';
                        })
                        .replace(/\//g,'\\\/');
     var reg = new RegExp(routeStr + '$');
     return reg;

 var path_regexp = pathRegexp("/article/:id/*/:name");
 console.log("path_regexp:" + path_regexp);


运行结果为:
D:\nodejs>node reg.js
(arg0):id
(arg1):id
(arg2):id
(arg3)id
(arg4)undefined
(arg5)undefined
(arg6)9
(arg7)/article/:id/(.*)/:name
(arg0):name
(arg1):name
(arg2)undefined
(arg3)undefined
(arg4):name
(arg5)name
(arg6)18
(arg7)/article/:id/(.*)/:name
path_regexp:/\/article\/(.*)\/(.*)\/(.*)$/
前三个参数都是一样的,按照上面的分析,我们可以分析如下:
arg0:整个匹配的结果
arg1:((:(.*?(?=\/)))|(:(.*(?=$)))匹配的结果,:id
arg2:(:(.*?(?=\/)))匹配的结果,:id
arg3:(.*?(?=\/))匹配的结果,id
arg4:(:(.*(?=$))的结果,undefined
arg5:(.*(?=$)的匹配结果,undefined
arg6:第一个':'出现的位置,9
arg7:整个目标字符串

第二轮:name的匹配读者自己去分析。

leo老师的网站:http://jsera.net/book/gyTCIRi5zx可以去看看哈



原创粉丝点击