不幸的是,由于 Javascript 的字符串replace()
函数不允许您从特定索引开始,并且无法对字符串进行就地修改,因此很难像在更理智的语言中那样有效地做到这一点。
.split().join()
这不是一个好的解决方案,因为它涉及创建大量字符串(尽管我怀疑 V8 做了一些黑魔法来优化它)。
- 循环调用
replace()
是一个糟糕的解决方案,因为 replace 每次都从字符串的开头开始搜索。这将导致 O(N^2) 行为!如此处的答案所述,它还存在无限循环问题。
- 如果您的替换字符串是编译时间常数,那么正则表达式可能是最好的解决方案,但如果不是,那么您就不能真正使用它。您绝对不应该尝试通过转义将任意字符串转换为正则表达式。
一种合理的方法是使用适当的替换来构建一个新字符串:
function replaceAll(input: string, from: string, to: string): string {
const fromLen = from.length;
let output = "";
let pos = 0;
for (;;) {
let matchPos = input.indexOf(from, pos);
if (matchPos === -1) {
output += input.slice(pos);
break;
}
output += input.slice(pos, matchPos);
output += to;
pos = matchPos + fromLen;
}
return output;
}
我将它与所有其他解决方案进行了基准测试(除了在循环中调用会很糟糕),它比正则表达式稍微快一点,大约是/replace()
的两倍。split
join
编辑:这与 Stefan Steiger 的回答几乎相同,由于某种原因我完全错过了。.join()
然而,由于某种原因,他的答案仍然使用,这使得它比我的慢 4 倍。