String.prototype.replace()

该方法作为字符串中非常常用的方法, 今天我们具体介绍一下它的用法

语法格式

someString.replace(regxp | substr, newStr | function)

第一个入参可以是正则或者是字符串, 如是字符串将不能设置忽略大小写, 在匹配到结果后返回, 而不继续匹配下去, 若是正则表达式则会按正则的意图进行匹配;

第二个入参是新字符串或者是回调函数, 若是新字符串则会替换匹配到的字符串, 如果是函数则在每次匹配到结果时执行该函数并把函数的返回值替换匹配到的字符串;

该方法不会破坏原来的字符串, 而且带有返回值, 返回的是一个部分或者全部由替代模式所取代的新的字符串, 以为有返回值, 所以支持链式调用;

第二个参数是字符串时

该字符串中可以插入以下特殊变量:

变量名

解释

$$

代表插入一个 $

$&

插入匹配的子串, 用来引用匹配到子串

$`

插入当前匹配到的子串左边的内容

$'

插入当前匹配到的子串的右边的内容

$n

如果第一个参数是正则, 并且 n 是个小于100的正整数, 那么插入第 n 个括号匹配的字符串

一些 Demo 如下:

let str = 'hello world';
str.replace('o', '$$');     // "hell$ world"
str.replace('o', '-$&-');   // "hell-o- world"
str.replace('o', '$`');     // "hellhell world"
str.replace('o', '$\'');    // "hell world world"
str.replace(/(o)|(d)/g, '-$1-$2');  // "hell-o- w-o-rl--d", 这个结果大家好好用心理解

第二个参数是函数时

在这种情况下,当匹配执行后, 该函数就会执行。 函数的返回值作为替换字符串。 (注意: 上面提到的特殊替换参数在这里不能被使用。) 另外要注意的是, 如果第一个参数是正则表达式, 并且其为全局匹配模式, 那么这个方法将被多次调用, 每次匹配都会被调用。该函数的入参解释:

函数入参位置

对应解释

match

匹配到的字符串

p1, p2, p3, ...

同上 $1, $2, $3

offset

匹配到的字符串在原字符串中的偏移量

string

原字符串

该函数的精确参数取决于第一个参数是不是正则表达式, 以及该正则里指定了多少个括号子串

// 如果我们要把字符串中的单词首字母大写, 可以进行如下操作
let str = 'hello world',
    reg = /(\w)(\w*)/g;

str.replace(reg, function(match, p1, p2, offset, str) {
    console.log(match, p1, offset, str);
    return p1.toUpperCase() + p2;
});

对于上面的函数中的入参大家可以打印一下看看, 并加以理解;
String.prototype.replace() 这个方法在字符串操作中使用非常频繁, 同时也由于其相对复杂的入参组合导致该方法非常灵活, 我们看一看在我们项目中使用它的场景; 掩码手机号 相信大家都做过, 我们看看使用 replace 如何实现:

// 假设我们有一个手机号
let tel = '13194099515',
    res = '',
    tmp = '****';

// 方法1:
res = tel.replace(/\d{4}(?=\d{4}$)/g, tmp);         // 第一个参数是正则

// 方法2: 
res = tel.replace(/(\d{3})(\d{4})/g, '$1' + tmp);   // 第一个参数是正则

// 方法3:
res = tel.replace(tel.slice(3, -4), tmp);           // 第一个参数是字符串

// 方法4:
res = tel.replace(/(\d{3})(\d{4})(\d{4})/g, function(match, p1, p2, p3) {
    return p1 + tmp + p3;
});

相信应该还有别的可以使用 replace() 实现的途径, 大家可以好好考虑一下;

小结

String.protype.replace() 方法使用比较灵活, 大家可以在项目中通过多使用来加深对它的理解和记忆, 一般对于简单匹配, 第二个参数可以使用简单字符串来操作, 如果要对替换控制的比较精细的话, 需要有一个比较清晰的正则做为第一个入参, 此时第二个入参可以使用回调函数进行精确控制。