前几天在群里发现有人发来了一段代码求问是什么意思
content = content.replace(reg, function($1, $2){
});
我是第一次见到replace的第二个参数竟然可以用函数(毕竟渣渣一枚。。。)然后看了菜鸟教程,第一个参数正则没什么其他异议(好像也可以是字符串,但重点不在这里),但是第二个参数既可以是字符串也可以是函数,并且如果是字符串的话,$符号有不同的含义
首先理解一个概念,比如一个正则表达式
/a\Sd\S/g
他可以匹配到"asdf","akdg"等等
而正则中的括号却有不同的含义
/(a\S)(d\S)/g
与上面匹配到的东西是完全一样的,但是他有了括号,就有了模式字符串即"asdf"匹配到/(a\S)(d\S)/的第一个模式字符串是"as",第二个模式字符串是"df"(这里笔者的模式字符串的定义可能不准确,只是笔者随口一叫的,有可能学名不是这个)
同理"akdg"匹配到/(a\S)(d\S)/的第一个模式字符串是"ak", 第二个模式字符串是"dg"
回到本意,replace的第二个参数为字符串并且拥有'$'和数字,代表匹配到的第几个模式字符串,比如‘$1’就是匹配到的第一个模式字符串
let str = "asdfqwerakdg";
str.replace(/(a\S)(d\S)/g, "$2$1");
str.replace(/(a\S)(d\S)/g, "$2$1") === "dfasqwerdgak";
注意看括号的位置,首先正则匹配到的第一个字符串是"asdf",针对这个正则匹配到的"asdf", $1===as $2===df。所以替换成$2$1九尾dfas
同理,正则匹配到的第二个字符串是"akdg",针对这个正则匹配到的"akdg", $1===ak $2===dg。所以替换成$2$1九尾dgak
所以答案就如上所示了。
理解了模式字符串的概念,当replace的第二个参数为函数的时候就方便理解了
str.replace(/(a\S)(d\S)/g, function(arg1, arg2, arg3, arg4, arg5){
console.log(arg1); // 第一遍输出asdf, 第二遍输出akdg
console.log(arg2); // 第一遍输出as, 第二遍输出ak ((匹配字符串))
console.log(arg3); // 第一遍输出df, 第二遍输出dg
console.log(arg4); // 第一遍输出0, 第二遍输出8
console.log(arg5); // 两次均输出"asdfqwerakdg
return arg1;
});
第一个参数为匹配到的字符串,第二个参数到第n+1个参数为n个模式字符串,第n+2个参数为匹配到的字符串的位置,第n+3个参数为字符串本身。