【问题标题】:Replace all occurrences in a string and avoid RegExp escaping替换字符串中的所有匹配项并避免 RegExp 转义
【发布时间】:2015-02-26 10:02:32
【问题描述】:

是否有可能在不损失性能的情况下用另一个字符串替换所有出现的子字符串,并完全避免在此过程中使用 RegExp? IE。从等式中删除 RegExp,以确保当您忘记正确转义 + 之类的内容时不会发生 RegExp 魔术。

'1+1 2+2'.replace('+', '-') -> only first "+" is replaced
'1+1 2+2'.replace(/\+/g, '-') -> undesired regexp complexities

更新 1

这并不能解决逃逸问题:

String.prototype.replaceAll= function(search, replace) {
    return this.replace(new RegExp(search, "g"), replace);
}

更新 2

执行程序化 unescape 会影​​响性能:

RegExp.quote = function(str) {
    return (str+'').replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&");
};

【问题讨论】:

标签: javascript string replace


【解决方案1】:

或者,基于 Florian Margaine 的代码和测试用例:

    window.replaceQuick = function(subject, search, replace) {
      var index = -1, offset = 0;
      var result = '';
      while ((index = subject.indexOf(search, offset)) !== -1) {
        result += subject.substring(offset, index) + replace;
        offset = index + search.length;
      }
      return result + search.substring(offset);
    }

由于我正在进行部分提取,它应该会获得更好的性能。

http://jsperf.com/replaceall-regex-or-not/3

【讨论】:

  • 好点,但仍然取决于用例和运行时。但通常正则表达式更好。但正如我们之前提到的,过早的优化..
  • 加一个因为是的...在某些情况下您的实现速度更快(正如弗洛里安指出的那样,性能测试中有一个错误)
  • 这个建议的 replaceQuick 函数可能是没有 RegExp 的最佳方法,因此从这个意义上说,它最好地回答了 OP 问题。但是除非你知道你在一个缓慢的 RegExp 引擎上运行并且性能影响确实很重要,否则为什么要麻烦呢?如果您在所有浏览器上进行测试并使用各种真实输入,RegExp 可能会更快。
【解决方案2】:
function replaceAll(str, search, replace) {
    while (str.indexOf(search) > -1) {
        str = str.replace(search, replace);
    }
    return str;
}

这行得通。但是,它比使用正则表达式更高效吗?让我们试试吧。

这是我作为基准的正则表达式函数:

function replaceAllRegex(str, search, replace) {
    return str.replace(new RegExp(search.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&"), 'g'), replace);
}

根据jsperf,非正则表达式版本约为 8k ops/sec,而正则表达式版本约为 123k ops/sec。 自动转义字符时。

您应该重新审视您对“转义是性能损失”的看法。

如果您想要的是性能,请使用正则表达式版本。

PS:Roel's version 可以比正则表达式更快。

【讨论】:

  • 手动转义不需要时间(我的意思是它需要你的时间,而不是 CPU 时间)。但是程序化的 unescape 显然需要一些 CPU 时间。
  • 这是相同的测试用例但包括程序转义jsperf.com/replaceall-regex-or-not/2
  • while(replace) 对我来说仍然慢了 32%。我想知道是否需要indexOf()。有没有办法知道replace() 是否真的做了什么?
  • @dystroy 将其包含在答案中。
  • @exebook 不,无法知道。 replace 返回新字符串。
猜你喜欢
  • 2011-08-29
  • 2020-06-23
  • 1970-01-01
  • 2012-02-07
  • 2016-09-26
  • 2020-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多