Javascript多重替换
在最新版本的大多数流行浏览器中,你可以使用replaceAll
,如下所示:
let result = "1 abc 2 abc 3".replaceAll("abc", "xyz"); // `result` is "1 xyz 2 xyz 3"
但首先要在Can I use或其他兼容性表中检查目标浏览器是否已经支持它。
对于Node.js和与旧版/非最新版浏览器的兼容性:
注意:不要在性能关键代码中使用以下解决方案。
作为对简单文字字符串的正则表达式的替代方案,你可以使用:
str = "Test abc test test abc test...".split("abc").join("");
一般的模式是:
str.split(search).join(replacement)
在某些情况下,这比使用replaceAll
和正则表达式要快,但在现代浏览器中似乎不再是这样。
结论:
如果你有一个性能关键的用例(例如,处理数百个字符串),请使用正则表达式方法。但对于大多数典型的用例,这很值得,不必担心特殊字符。
我不建议在目前(2020年)使用replaceAll
。它不被一些在今年进行更新的浏览器支持。caniuse.com/?search=replaceAll 现在还为时过早。
NodeJS在15.x版本中支持replaceAll
。
在区分大小写的情况下该怎么办?
基准测试中的普通替换函数不等同于正则表达式的/g。"如果模式是一个字符串,只有第一次出现的地方会被替换。" 例如:replaceAll_0("foo bar foo") => "bar foo",但实际上应该是"bar"。-MDN
这些解决方案比基于正则表达式的解决方案更易读。我认为这应该是最佳答案。
在JavaScript中,有两种方法可以实现多重替换,分别是正则表达式和分割和拼接。正则表达式方法是使用`replace`函数和正则表达式的全局修饰符`g`进行替换,而分割和拼接方法是使用`split`函数将字符串分割成数组,然后使用`join`函数将数组拼接成字符串。
然而,需要注意的是,JavaScript中不推荐扩展内置原型。上述代码中的`replaceAll`方法是通过对`String`原型进行扩展来实现的,仅供演示不同实现方式。
在性能方面,有人对正则表达式和分割和拼接方法进行了比较。在Chrome Windows 8机器上,正则表达式方法比分割和拼接方法快53%。这意味着对于给定的输入,正则表达式方法的速度是分割和拼接方法的两倍。
此外,正则表达式方法在处理包含正则表达式特殊字符的搜索字符串时可能会出现问题。因此,使用正则表达式方法时,需要确保搜索字符串已经转义或者不包含正则表达式特殊字符。
如果需要转义字符串,可以使用MDN提供的`escapeRegExp`函数。可以在`String.prototype.replaceAll`方法中调用`escapeRegExp`函数来实现转义。然而,需要注意这可能会对性能产生影响。
需要注意的是,在2021年,JavaScript中已经原生支持了`String.prototype.replaceAll()`方法,因此在使用之前应该先检查是否已经存在该方法。
对于在nestjs中使用时出现的`replaceAll is not method of String prototype`错误,可以尝试检查是否使用了正确的语法或者查看nestjs的相关文档来解决这个问题。
在2020年8月,现代浏览器已经支持ECMAScript 2021语言规范中定义的String.replaceAll()方法。
但是,对于旧版本/遗留浏览器,可以使用以下代码进行替换操作:
function escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& 表示匹配的整个字符串 } function replaceAll(str, find, replace) { return str.replace(new RegExp(escapeRegExp(find), 'g'), replace); }
以上是最初的解决方案,后来根据不同评论的反馈进行了改进。
如果需要将'abc'作为变量传递进来,可以使用下面的代码:
var find = 'abc'; var re = new RegExp(find, 'g'); str = str.replace(re, '');
对于这个问题,还有一个更简化的解决方案,如下所示:
function replaceAll(str, find, replace) { return str.replace(new RegExp(find, 'g'), replace); }
需要注意的是,正则表达式中包含特殊字符,因此在传递参数到find函数之前,需要对其进行预处理以转义这些字符。可以使用以下函数进行转义:
function escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& 表示匹配的整个字符串 }
为了使replaceAll()函数更安全,可以将其修改如下,同时引入escapeRegExp()函数:
function replaceAll(str, find, replace) { return str.replace(new RegExp(escapeRegExp(find), 'g'), replace); }
在escapeRegExp函数中,']'和'}'是多余的,不需要转义。最好的做法是使用.replace(/[.^$*+?()[{|\\]/g, "\\$&")进行转义。
还需要注意对替换字符串进行转义(考虑escapeRegExp函数在替换字符串中使用$&的特殊行为)。将最后一个代码块中的replace替换为replace.replace(/\$/g, '$$$$')。详情请参考stackoverflow.com/a/6969486/2730641。测试用例:replaceAll('abc def abc', 'abc', '$&@%#!') // Censor 'abc'
此外,还提到了关于replaceAll()方法的评论,并提到了stackoverflow.com/a/63587267/8798220中的评论。
总结一下,Javascript中没有内置的多重替换方法String.replaceAll()。为了在旧版本浏览器中实现多重替换,可以使用正则表达式和replace方法结合的方式来实现。通过对传入的字符串进行转义处理,可以确保正则表达式中的特殊字符不会引起错误。