JavaScript 内建的 String.prototype.replace
函数,如果传入的第一个参数是字符串,那么替换行为只会发生一次。如果需要将一个字符串内所有某子字符串都替换掉,往往需要一些额外的操作。以下提供一些可行的方案:
- 使用循环进行多次替换
最直观的想法,就是替换完成后通过 indexOf
等方案查找字符串,如果还有就继续替换:
function replace(input, from, to) {
while (input.indexOf(from) >= 0) input = input.replace(input, from, to);
return input;
}
当然,这并不是一个优雅的解决方案。
- 使用正则表达式
String.prototype.replace
支持第一个参数传递正则表达式。有了正则表达式,只要设置上 g
标签,就可以全局匹配并替换所有的情况了。示例代码如下:
function replace(input, from, to) {
return input.replace(new RegExp(from, 'g'), to);
}
这个方案的劣势在于,如果需要替换的内容中含有某些正则表达式特有的匹配符号,可能会导致非预期的结果。举个例子来说,如果希望把 .+
这个字符串替换成 +.
这样,上面的函数并不能达到预期的效果,因为 .+
在正则表达式中可以匹配任意的字符。replace('hello.+world', '.+', '+.')
的执行结果是 +.
。
- 使用
split
&join
这是一个比较取巧的方案,先用 split
函数将字符串进行拆分,然后再用 join
将拆分后的结果重新拼接起来。示例代码如下:
function replace(input, from, to) {
return input.split(from).join(to);
}
这个方案代码比较简洁,也不会有正则表达式中提到的问题。虽然计算会产生中间变量(数组),但只要不是频繁或在大规模数据上使用,效率的影响可以忽略不计。