如何替换字符串的所有出现?

发布于 2025-02-12 03:22:17 字数 255 浏览 3 评论 0 原文

给定一个字符串:

string = "Test abc test test abc test test test abc test test abc";

这似乎仅删除上面字符串中的 abc 的第一次出现:

string = string.replace('abc', '');

如何替换 all 出现它?

Given a string:

string = "Test abc test test abc test test test abc test test abc";

This seems to only remove the first occurrence of abc in the string above:

string = string.replace('abc', '');

How do I replace all occurrences of it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

吾性傲以野 2025-02-19 03:22:18

截至2020年8月: 现代浏览器对 =“ https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/string/replaceall/replaceall” rel =“ noreferrer”> string.replaceall(replaceall(Replaceall() /a>由ecmascript 2021语言规范定义。


对于较旧/旧的浏览器:

function escapeRegExp(str) {
  return str.replace(/[.*+?^${}()|[\]\\]/g, '\\
amp;'); // 
amp; means the whole matched string
}

function replaceAll(str, find, replace) {
  return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}

这是如何演变的:

str = str.replace(/abc/g, '');

回答评论“如果'abc'作为变量是什么

var find = 'abc';
var re = new RegExp(find, 'g');

str = str.replace(re, '');

? stackoverflow.com/users/49153/click-upvote"> click upvote 的评论,您可以更简化它:

function replaceAll(str, find, replace) {
  return str.replace(new RegExp(find, 'g'), replace);
}

注意:正则表达式包含特殊(meta)字符,以及AS在中盲目地通过一个参数在上面找到函数而无需预处理以逃脱这些字符是危险的。 mozilla开发人员网络's javaScript指南正式表达式指南,它们呈现以下实用程序功能(至少已更改了至少已更改由于此答案最初是两次,因此请确保检查MDN站点是否有潜在的更新):

function escapeRegExp(string) {
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\
amp;'); // 
amp; means the whole matched string
}

因此,为了使 felpaceAll()函数上述更安全,可以将其修改为以下内容。还包括 Escaperegexp

function replaceAll(str, find, replace) {
  return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}

As of August 2020: Modern browsers have support for the String.replaceAll() method defined by the ECMAScript 2021 language specification.


For older/legacy browsers:

function escapeRegExp(str) {
  return str.replace(/[.*+?^${}()|[\]\\]/g, '\\
amp;'); // 
amp; means the whole matched string
}

function replaceAll(str, find, replace) {
  return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}

Here is how this answer evolved:

str = str.replace(/abc/g, '');

In response to comment "what's if 'abc' is passed as a variable?":

var find = 'abc';
var re = new RegExp(find, 'g');

str = str.replace(re, '');

In response to Click Upvote's comment, you could simplify it even more:

function replaceAll(str, find, replace) {
  return str.replace(new RegExp(find, 'g'), replace);
}

Note: Regular expressions contain special (meta) characters, and as such it is dangerous to blindly pass an argument in the find function above without pre-processing it to escape those characters. This is covered in the Mozilla Developer Network's JavaScript Guide on Regular Expressions, where they present the following utility function (which has changed at least twice since this answer was originally written, so make sure to check the MDN site for potential updates):

function escapeRegExp(string) {
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\
amp;'); // 
amp; means the whole matched string
}

So in order to make the replaceAll() function above safer, it could be modified to the following if you also include escapeRegExp:

function replaceAll(str, find, replace) {
  return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}
飘然心甜 2025-02-19 03:22:18

为了完整,我必须考虑应该使用哪种方法来执行此操作。如本页面上的其他答案所建议的,基本上有两种方法可以做到这一点。

注意:通常,通常不建议在JavaScript中扩展内置原型。我仅出于插图的目的而作为字符串原型上的扩展名提供,显示了 String 内置原型的假设标准方法的不同实现。


基于正则表达式的实施

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.replace(new RegExp(search, 'g'), replacement);
};

拆分和加入(功能)实现对

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.split(search).join(replacement);
};

正则表达方式在效率方面的工作方式不太了解,我倾向于倾向于拆分并在过去而无需考虑性能的情况下加入实施。当我确实想知道哪个更有效,而从哪个边距开始时,我以此为借口找出答案。

在我的Chrome Windows  8机器上,基于正则表达式的实现是最快的拆分,加入实现速度慢了53%。这意味着我使用的lorem ipsum输入的正则表达式是两倍。

查看此 基准 互相运行这两个实现。


如@thomasleduc和其他其他评论中所述,如果 search 包含某些保留为正式表达式中的特殊字符。该实现假设呼叫者将事先逃脱字符串,或者仅通过 正则表达式 (mdn)。

MDN还提供了一种实现,以逃避我们的字符串。如果它也标准化为 Regexp.Escape(str),那将是很好的,但是,不存在:

function escapeRegExp(str) {
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\
amp;"); // 
amp; means the whole matched string
}

我们可以在我们的字符串中调用 Escaperegexp 。 prototype.replaceall 实现,但是,我不确定这会影响性能有多大(即使对于不需要逃脱的字符串,也可能像所有字母数字字符串一样)。

For the sake of completeness, I got to thinking about which method I should use to do this. There are basically two ways to do this as suggested by the other answers on this page.

Note: In general, extending the built-in prototypes in JavaScript is generally not recommended. I am providing as extensions on the String prototype simply for purposes of illustration, showing different implementations of a hypothetical standard method on the String built-in prototype.


Regular Expression Based Implementation

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.replace(new RegExp(search, 'g'), replacement);
};

Split and Join (Functional) Implementation

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.split(search).join(replacement);
};

Not knowing too much about how regular expressions work behind the scenes in terms of efficiency, I tended to lean toward the split and join implementation in the past without thinking about performance. When I did wonder which was more efficient, and by what margin, I used it as an excuse to find out.

On my Chrome Windows 8 machine, the regular expression based implementation is the fastest, with the split and join implementation being 53% slower. Meaning the regular expressions are twice as fast for the lorem ipsum input I used.

Check out this benchmark running these two implementations against each other.


As noted in the comment below by @ThomasLeduc and others, there could be an issue with the regular expression-based implementation if search contains certain characters which are reserved as special characters in regular expressions. The implementation assumes that the caller will escape the string beforehand or will only pass strings that are without the characters in the table in Regular Expressions (MDN).

MDN also provides an implementation to escape our strings. It would be nice if this was also standardized as RegExp.escape(str), but alas, it does not exist:

function escapeRegExp(str) {
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\
amp;"); // 
amp; means the whole matched string
}

We could call escapeRegExp within our String.prototype.replaceAll implementation, however, I'm not sure how much this will affect the performance (potentially even for strings for which the escape is not needed, like all alphanumeric strings).

2025-02-19 03:22:18

在最受欢迎的浏览器的最新版本中,您可以使用 替换
如下所示:

let result = "1 abc 2 abc 3".replaceAll("abc", "xyz");
// `result` is "1 xyz 2 xyz 3"

但是检查我可以首先使用或其他兼容性表,以确保您是浏览器定位首先增加了对其的支持。


对于node.js以及与较旧/非电流浏览器的兼容性:

注意:不要在performance关键代码中使用以下解决方案。

作为简单文字字符串的正则表达式的替代方案,您可以使用

str = "Test abc test test abc test...".split("abc").join("");

一般模式

str.split(search).join(replacement)

在某些情况下比使用替换和正则表达式更快,但是在现代浏览器中似乎不再是这种情况。

基准: https://jsben.ch/tzyzj

结论:

如果您有绩效 - 关键用例(例如,处理数百个字符串),使用正则表达方法。但是对于大多数典型的用例,这是值得不必担心特殊角色的。

In the latest versions of most popular browsers, you can use replaceAll
as shown here:

let result = "1 abc 2 abc 3".replaceAll("abc", "xyz");
// `result` is "1 xyz 2 xyz 3"

But check Can I use or another compatibility table first to make sure the browsers you're targeting have added support for it first.


For Node.js and compatibility with older/non-current browsers:

Note: Don't use the following solution in performance critical code.

As an alternative to regular expressions for a simple literal string, you could use

str = "Test abc test test abc test...".split("abc").join("");

The general pattern is

str.split(search).join(replacement)

This used to be faster in some cases than using replaceAll and a regular expression, but that doesn't seem to be the case anymore in modern browsers.

Benchmark: https://jsben.ch/TZYzj

Conclusion:

If you have a performance-critical use case (e.g., processing hundreds of strings), use the regular expression method. But for most typical use cases, this is well worth not having to worry about special characters.

一紙繁鸢 2025-02-19 03:22:18

这些是最常见和可读的方法。

var str = "Test abc test test abc test test test abc test test abc"

方法1:

str = str.replace(/abc/g, "replaced text");

方法2:

str = str.split("abc").join("replaced text");

方法3:

str = str.replace(new RegExp("abc", "g"), "replaced text");

方法4:

while(str.includes("abc")){
   str = str.replace("abc", "replaced text");
}

输出:

console.log(str);
// Test replaced text test test replaced text test test test replaced text test test replaced text

These are the most common and readable methods.

var str = "Test abc test test abc test test test abc test test abc"

Method 1:

str = str.replace(/abc/g, "replaced text");

Method 2:

str = str.split("abc").join("replaced text");

Method 3:

str = str.replace(new RegExp("abc", "g"), "replaced text");

Method 4:

while(str.includes("abc")){
   str = str.replace("abc", "replaced text");
}

Output:

console.log(str);
// Test replaced text test test replaced text test test test replaced text test test replaced text
海夕 2025-02-19 03:22:18

使用单词边界( \ b ),

'a cat is not a caterpillar'.replace(/\bcat\b/gi,'dog');
//"a dog is not a caterpillar"

这是一个简单的正则义务,避免在大多数情况下更换单词的一部分。但是,Dash - 仍然被视为单词边界。因此,可以在这种情况下使用条件,以避免替换诸如 cool-cat 之类的字符串:

'a cat is not a cool-cat'.replace(/\bcat\b/gi,'dog');//wrong
//"a dog is not a cool-dog" -- nips
'a cat is not a cool-cat'.replace(/(?:\b([^-]))cat(?:\b([^-]))/gi,'$1dog$2');
//"a dog is not a cool-cat"

基本上,此问题与这里的问题相同:
replace''''''with javascript

子弦的多次出现,远非如此。思考灵活,想想分裂!

var newText = "the cat looks like a cat".split('cat').join('dog');

另外,为了防止更换单词零件 - 批准的答案也将做到!您可以使用我承认的正则表达式解决此问题,这些表达式更为复杂,并且作为其中的结果,也会慢一点:

var regText = "the cat looks like a cat".replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");

输出与可接受的答案但是,使用/cat/g 在此字符串上的表达:

var oops = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/cat/g,'dog');
//returns "the dog looks like a dog, not a dogerpillar or cooldog" ??

确实,这可能不是您想要的。那是什么?恕我直言,只有有条件地替代“猫”的正则(即,不是单词的一部分),就像这样:

var caterpillar = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");
//return "the dog looks like a dog, not a caterpillar or coolcat"

我的猜测是,这满足了您的需求。当然,这不是万无一失的,但是应该足以让您开始。我建议您阅读有关这些页面的更多信息。这将证明在完善此表达式以满足您的特定需求时很有用。


这是 .replace的示例。 与回调功能一起使用。在这种情况下,它极大地简化了表达式的灵活性,例如用正确的资本化替换或同时替换 cat cat> cats :

'Two cats are not 1 Cat! They\'re just cool-cats, you caterpillar'
   .replace(/(^|.\b)(cat)(s?\b.|$)/gi,function(all,char1,cat,char2)
    {
       // Check 1st, capitalize if required
       var replacement = (cat.charAt(0) === 'C' ? 'D' : 'd') + 'og';
       if (char1 === ' ' && char2 === 's')
       { // Replace plurals, too
           cat = replacement + 's';
       }
       else
       { // Do not replace if dashes are matched
           cat = char1 === '-' || char2 === '-' ? cat : replacement;
       }
       return char1 + cat + char2;//return replacement string
    });
//returns:
//Two dogs are not 1 Dog! They're just cool-cats, you caterpillar

Use word boundaries (\b)

'a cat is not a caterpillar'.replace(/\bcat\b/gi,'dog');
//"a dog is not a caterpillar"

This is a simple regex that avoids replacing parts of words in most cases. However, a dash - is still considered a word boundary. So conditionals can be used in this case to avoid replacing strings like cool-cat:

'a cat is not a cool-cat'.replace(/\bcat\b/gi,'dog');//wrong
//"a dog is not a cool-dog" -- nips
'a cat is not a cool-cat'.replace(/(?:\b([^-]))cat(?:\b([^-]))/gi,'$1dog$2');
//"a dog is not a cool-cat"

Basically, this question is the same as the question here:
Replace " ' " with " '' " in JavaScript

Regexp isn't the only way to replace multiple occurrences of a substring, far from it. Think flexible, think split!

var newText = "the cat looks like a cat".split('cat').join('dog');

Alternatively, to prevent replacing word parts—which the approved answer will do, too! You can get around this issue using regular expressions that are, I admit, somewhat more complex and as an upshot of that, a tad slower, too:

var regText = "the cat looks like a cat".replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");

The output is the same as the accepted answer, however, using the /cat/g expression on this string:

var oops = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/cat/g,'dog');
//returns "the dog looks like a dog, not a dogerpillar or cooldog" ??

Oops indeed, this probably isn't what you want. What is, then? IMHO, a regex that only replaces 'cat' conditionally (i.e., not part of a word), like so:

var caterpillar = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");
//return "the dog looks like a dog, not a caterpillar or coolcat"

My guess is, this meets your needs. It's not foolproof, of course, but it should be enough to get you started. I'd recommend reading some more on these pages. This'll prove useful in perfecting this expression to meet your specific needs.


Here is an example of .replace used with a callback function. In this case, it dramatically simplifies the expression and provides even more flexibility, like replacing with correct capitalisation or replacing both cat and cats in one go:

'Two cats are not 1 Cat! They\'re just cool-cats, you caterpillar'
   .replace(/(^|.\b)(cat)(s?\b.|$)/gi,function(all,char1,cat,char2)
    {
       // Check 1st, capitalize if required
       var replacement = (cat.charAt(0) === 'C' ? 'D' : 'd') + 'og';
       if (char1 === ' ' && char2 === 's')
       { // Replace plurals, too
           cat = replacement + 's';
       }
       else
       { // Do not replace if dashes are matched
           cat = char1 === '-' || char2 === '-' ? cat : replacement;
       }
       return char1 + cat + char2;//return replacement string
    });
//returns:
//Two dogs are not 1 Dog! They're just cool-cats, you caterpillar
活雷疯 2025-02-19 03:22:18

与全球正则表达式匹配:

anotherString = someString.replace(/cat/g, 'dog');

Match against a global regular expression:

anotherString = someString.replace(/cat/g, 'dog');
南街九尾狐 2025-02-19 03:22:18
str = str.replace(/abc/g, '');

或尝试此答案

str = str.replaceAll('abc', '');

或:

var search = 'abc';
str = str.replaceAll(search, '');

编辑:澄清 replaceAll 可用性

fellaceall 方法添加到 string 的原型。这意味着它将适用于所有字符串对象/文字。

例子:

var output = "test this".replaceAll('this', 'that'); // output is 'test that'.
output = output.replaceAll('that', 'this'); // output is 'test this'
str = str.replace(/abc/g, '');

Or try the replaceAll method, as recommended in this answer:

str = str.replaceAll('abc', '');

or:

var search = 'abc';
str = str.replaceAll(search, '');

EDIT: Clarification about replaceAll availability

The replaceAll method is added to String's prototype. This means it will be available for all string objects/literals.

Example:

var output = "test this".replaceAll('this', 'that'); // output is 'test that'.
output = output.replaceAll('that', 'this'); // output is 'test this'
愿得七秒忆 2025-02-19 03:22:18

使用正则表达式:

str.replace(/abc/g, '');

Use a regular expression:

str.replace(/abc/g, '');
空城缀染半城烟沙 2025-02-19 03:22:18

今天的表现

今天27.12.2019我在

结论

  • str.replace(/abc/g,''); c )是所有字符串的良好跨浏览器快速解决方案。
  • 基于 split-join a,b )或替换 c,d )的解决方案是
  • 基于快速解决方案的()( e,f,g,h )的速度很慢 - 通常,小字符串慢了4倍,大约3000次(
  • !解决方案( ra,rb )很慢,不适用于长字符串,

我还创建了自己的解决方案。看来目前是做问题作业的最短的:

str.split`abc`.join``

str = "Test abc test test abc test test test abc test test abc";
str = str.split`abc`.join``

console.log(str);

详细信息

测试是在Chrome 79.0,Safari 13.0.4和Firefox 71.0(64位)上进行的。测试 RA RB 使用递归。结果

短字符串 - 55个字符

可以在计算机上运行测试在这里。 Chrome的结果:

“在此处输入图像描述”

长字符串:275 000个字符

递归解决方案 ra rb 给出

连击:最大呼叫堆栈大小超过

1M字符的最大呼叫堆栈大小,甚至可以打破Chrome

”在此处输入图像描述”

我尝试为其他解决方案执行1M字符的测试,但是 e,f,g,g,h 都这样做浏览器要求我打破脚本的很多时间,所以我将测试字符串缩小到275K字符。您可以在计算机上运行测试在这里。 Chrome

“在此处输入图像说明“

测试中使用的代码

var t="Test abc test test abc test test test abc test test abc"; // .repeat(5000)
var log = (version,result) => console.log(`${version}: ${result}`);


function A(str) {
  return str.split('abc').join('');
}

function B(str) {
  return str.split`abc`.join``; // my proposition
}


function C(str) {
  return str.replace(/abc/g, '');
}

function D(str) {
  return str.replace(new RegExp("abc", "g"), '');
}

function E(str) {
  while (str.indexOf('abc') !== -1) { str = str.replace('abc', ''); }
  return str;
}

function F(str) {
  while (str.indexOf('abc') !== -1) { str = str.replace(/abc/, ''); }
  return str;
}

function G(str) {
  while(str.includes("abc")) { str = str.replace('abc', ''); }
  return str;
}

// src: https://stackoverflow.com/a/56989553/860099
function H(str)
{
    let i = -1
    let find = 'abc';
    let newToken = '';

    if (!str)
    {
        if ((str == null) && (find == null)) return newToken;
        return str;
    }

    while ((
        i = str.indexOf(
            find, i >= 0 ? i + newToken.length : 0
        )) !== -1
    )
    {
        str = str.substring(0, i) +
            newToken +
            str.substring(i + find.length);
    }
    return str;
}

// src: https://stackoverflow.com/a/22870785/860099
function RA(string, prevstring) {
  var omit = 'abc';
  var place = '';
  if (prevstring && string === prevstring)
    return string;
  prevstring = string.replace(omit, place);
  return RA(prevstring, string)
}

// src: https://stackoverflow.com/a/26107132/860099
function RB(str) {
  var find = 'abc';
  var replace = '';
  var i = str.indexOf(find);
  if (i > -1){
    str = str.replace(find, replace);
    i = i + replace.length;
    var st2 = str.substring(i);
    if(st2.indexOf(find) > -1){
      str = str.substring(0,i) + RB(st2, find, replace);
    }
  }
  return str;
}




log('A ', A(t));
log('B ', B(t));
log('C ', C(t));
log('D ', D(t));
log('E ', E(t));
log('F ', F(t));
log('G ', G(t));
log('H ', H(t));
log('RA', RA(t)); // use reccurence
log('RB', RB(t)); // use reccurence
<p style="color:red">This snippet only presents codes used in tests. It not perform test itself!<p>

Performance

Today 27.12.2019 I perform tests on macOS v10.13.6 (High Sierra) for the chosen solutions.

Conclusions

  • The str.replace(/abc/g, ''); (C) is a good cross-browser fast solution for all strings.
  • Solutions based on split-join (A,B) or replace (C,D) are fast
  • Solutions based on while (E,F,G,H) are slow - usually ~4 times slower for small strings and about ~3000 times (!) slower for long strings
  • The recurrence solutions (RA,RB) are slow and do not work for long strings

I also create my own solution. It looks like currently it is the shortest one which does the question job:

str.split`abc`.join``

str = "Test abc test test abc test test test abc test test abc";
str = str.split`abc`.join``

console.log(str);

Details

The tests were performed on Chrome 79.0, Safari 13.0.4 and Firefox 71.0 (64 bit). The tests RA and RB use recursion. Results

Enter image description here

Short string - 55 characters

You can run tests on your machine HERE. Results for Chrome:

Enter image description here

Long string: 275 000 characters

The recursive solutions RA and RB gives

RangeError: Maximum call stack size exceeded

For 1M characters they even break Chrome

enter image description here

I try to perform tests for 1M characters for other solutions, but E,F,G,H takes so much time that browser ask me to break script so I shrink test string to 275K characters. You can run tests on your machine HERE. Results for Chrome

enter image description here

Code used in tests

var t="Test abc test test abc test test test abc test test abc"; // .repeat(5000)
var log = (version,result) => console.log(`${version}: ${result}`);


function A(str) {
  return str.split('abc').join('');
}

function B(str) {
  return str.split`abc`.join``; // my proposition
}


function C(str) {
  return str.replace(/abc/g, '');
}

function D(str) {
  return str.replace(new RegExp("abc", "g"), '');
}

function E(str) {
  while (str.indexOf('abc') !== -1) { str = str.replace('abc', ''); }
  return str;
}

function F(str) {
  while (str.indexOf('abc') !== -1) { str = str.replace(/abc/, ''); }
  return str;
}

function G(str) {
  while(str.includes("abc")) { str = str.replace('abc', ''); }
  return str;
}

// src: https://stackoverflow.com/a/56989553/860099
function H(str)
{
    let i = -1
    let find = 'abc';
    let newToken = '';

    if (!str)
    {
        if ((str == null) && (find == null)) return newToken;
        return str;
    }

    while ((
        i = str.indexOf(
            find, i >= 0 ? i + newToken.length : 0
        )) !== -1
    )
    {
        str = str.substring(0, i) +
            newToken +
            str.substring(i + find.length);
    }
    return str;
}

// src: https://stackoverflow.com/a/22870785/860099
function RA(string, prevstring) {
  var omit = 'abc';
  var place = '';
  if (prevstring && string === prevstring)
    return string;
  prevstring = string.replace(omit, place);
  return RA(prevstring, string)
}

// src: https://stackoverflow.com/a/26107132/860099
function RB(str) {
  var find = 'abc';
  var replace = '';
  var i = str.indexOf(find);
  if (i > -1){
    str = str.replace(find, replace);
    i = i + replace.length;
    var st2 = str.substring(i);
    if(st2.indexOf(find) > -1){
      str = str.substring(0,i) + RB(st2, find, replace);
    }
  }
  return str;
}




log('A ', A(t));
log('B ', B(t));
log('C ', C(t));
log('D ', D(t));
log('E ', E(t));
log('F ', F(t));
log('G ', G(t));
log('H ', H(t));
log('RA', RA(t)); // use reccurence
log('RB', RB(t)); // use reccurence
<p style="color:red">This snippet only presents codes used in tests. It not perform test itself!<p>

鯉魚旗 2025-02-19 03:22:18

循环它直到数字出现为0,因此:

function replaceAll(find, replace, str) {
    while (str.indexOf(find) > -1) {
        str = str.replace(find, replace);
    }
    return str;
}

Loop it until number occurrences comes to 0, like this:

function replaceAll(find, replace, str) {
    while (str.indexOf(find) > -1) {
        str = str.replace(find, replace);
    }
    return str;
}
最丧也最甜 2025-02-19 03:22:18

这是最快的版本,不使用正则表达式

修订后的jsperf

replaceAll = function(string, omit, place, prevstring) {
  if (prevstring && string === prevstring)
    return string;
  prevstring = string.replace(omit, place);
  return replaceAll(prevstring, omit, place, string)
}

几乎 很快作为拆分和加入方法。

正如这里的评论中指出的那样,如果您的省略变量包含 plot ,如: replaceAceAll(“ string”,“ s”,“,” SS”),因为它将始终能够替换单词的另一个出现。

我的递归替换上还有另一个带有变体的jsperf,它的变化更快( http:// jsperf.com/replace-all-vs-split-join/12 )!

  • 2017年7月27日更新:Regexp现在在最近发布的Chrome 59中的性能最快。

This is the fastest version that doesn't use regular expressions.

Revised jsperf

replaceAll = function(string, omit, place, prevstring) {
  if (prevstring && string === prevstring)
    return string;
  prevstring = string.replace(omit, place);
  return replaceAll(prevstring, omit, place, string)
}

It is almost twice as fast as the split and join method.

As pointed out in a comment here, this will not work if your omit variable contains place, as in: replaceAll("string", "s", "ss"), because it will always be able to replace another occurrence of the word.

There is another jsperf with variants on my recursive replace that go even faster (http://jsperf.com/replace-all-vs-split-join/12)!

  • Update July 27th 2017: It looks like RegExp now has the fastest performance in the recently released Chrome 59.
无需解释 2025-02-19 03:22:18

如果您想找到的已经在字符串中,并且您没有正则逃逸者方便,则可以使用Join/Split:

function replaceMulti(haystack, needle, replacement)
{
    return haystack.split(needle).join(replacement);
}

someString = 'the cat looks like a cat';
console.log(replaceMulti(someString, 'cat', 'dog'));

If what you want to find is already in a string, and you don't have a regex escaper handy, you can use join/split:

function replaceMulti(haystack, needle, replacement)
{
    return haystack.split(needle).join(replacement);
}

someString = 'the cat looks like a cat';
console.log(replaceMulti(someString, 'cat', 'dog'));

叶落知秋 2025-02-19 03:22:18

当然在 2021 正确的答案是:

string.prototype.replaceall()

console.log(
  'Change this and this for me'.replaceAll('this','that') // Normal case
);
console.log(
  'aaaaaa'.replaceAll('aa','a') // Challenged case
);

如果您不想处理 + noreferrer“> regexp

但是,如果浏览器从2020年开始?

在这种情况下,我们需要 (强迫较旧的浏览器支持新功能)(我认为需要几年的时间)
我找不到答案中完全正确的方法。因此,我建议将此功能定义为多填充。

我建议的替换 polyfill的建议选项:

fellaceAll polyfill(带有global-flag错误)(更有原则的版本)
if (!String.prototype.replaceAll) { // Check if the native function not exist
    Object.defineProperty(String.prototype, 'replaceAll', { // Define replaceAll as a prototype for (Mother/Any) String
        configurable: true, writable: true, enumerable: false, // Editable & non-enumerable property (As it should be)
        value: function(search, replace) { // Set the function by closest input names (For good info in consoles)
            return this.replace( // Using native String.prototype.replace()
                Object.prototype.toString.call(search) === '[object RegExp]' // IsRegExp?
                    ? search.global // Is the RegEx global?
                        ? search // So pass it
                        : function(){throw new TypeError('replaceAll called with a non-global RegExp argument')}() // If not throw an error
                    : RegExp(String(search).replace(/[.^$*+?()[{|\\]/g, "\\
amp;"), "g"), // Replace all reserved characters with '\' then make a global 'g' RegExp
                replace); // passing second argument
        }
    });
}
fellaceall polyfill(处理Global-flag(处理Global-Flag) (我的第一个偏爱) - 为什么
if (!String.prototype.replaceAll) { // Check if the native function not exist
    Object.defineProperty(String.prototype, 'replaceAll', { // Define replaceAll as a prototype for (Mother/Any) String
        configurable: true, writable: true, enumerable: false, // Editable & non-enumerable property (As it should be)
        value: function(search, replace) { // Set the function by closest input names (For good info in consoles)
            return this.replace( // Using native String.prototype.replace()
                Object.prototype.toString.call(search) === '[object RegExp]' // IsRegExp?
                    ? search.global // Is the RegEx global?
                        ? search // So pass it
                        : RegExp(search.source, /\/([a-z]*)$/.exec(search.toString())[1] + 'g') // If not, make a global clone from the RegEx
                    : RegExp(String(search).replace(/[.^$*+?()[{|\\]/g, "\\
amp;"), "g"), // Replace all reserved characters with '\' then make a global 'g' RegExp
                replace); // passing second argument
        }
    });
}
?第一个偏好):
if(!String.prototype.replaceAll){Object.defineProperty(String.prototype,'replaceAll',{configurable:!0,writable:!0,enumerable:!1,value:function(search,replace){return this.replace(Object.prototype.toString.call(search)==='[object RegExp]'?search.global?search:RegExp(search.source,/\/([a-z]*)$/.exec(search.toString())[1]+'g'):RegExp(String(search).replace(/[.^$*+?()[{|\\]/g,"\\
amp;"),"g"),replace)}})}
尝试:

if(!String.prototype.replaceAll){Object.defineProperty(String.prototype,'replaceAll',{configurable:!0,writable:!0,enumerable:!1,value:function(search,replace){return this.replace(Object.prototype.toString.call(search)==='[object RegExp]'?search.global?search:RegExp(search.source,/\/([a-z]*)$/.exec(search.toString())[1]+'g'):RegExp(String(search).replace(/[.^$*+?()[{|\\]/g,"\\
amp;"),"g"),replace)}})}

console.log(
  'Change this and this for me'.replaceAll('this','that')
); // Change that and that for me

console.log(
  'aaaaaa'.replaceAll('aa','a')
); // aaa

console.log(
  '{} (*) (*) (RegEx) (*) (\*) (\\*) [reserved characters]'.replaceAll('(*)','X')
); // {} X X (RegEx) X X (\*) [reserved characters]

console.log(
  'How (replace) (XX) with $1?'.replaceAll(/(xx)/gi,'$1')
); // How (replace) ($1) with $1?

console.log(
  'Here is some numbers 1234567890 1000000 123123.'.replaceAll(/\d+/g,'***')
); // Here is some numbers *** *** *** and need to be replaced.

console.log(
  'Remove numbers under 233: 236   229  711   200   5'.replaceAll(/\d+/g, function(m) {
    return parseFloat(m) < 233 ? '' : m
  })
); // Remove numbers under 233: 236     711

console.log(
  'null'.replaceAll(null,'x')
); // x


// The difference between My first preference and the original:
// Now in 2022 with browsers > 2020 it should throw an error (But possible it be changed in future)

//   console.log(
//      'xyz ABC abc ABC abc xyz'.replaceAll(/abc/i,'')
//   );

// Browsers < 2020:
// xyz     xyz
// Browsers > 2020
// TypeError: String.prototype.replaceAll called with a non-global RegExp

浏览器支持:

结果与本机替换相同,如果第一个参数输入为:
null 未定义代码> REGEXP 号码字符串,...

ref: 22.1.3.19 string.prototype.replaceall(searchValue,repenterValue)
+

重要说明:正如一些专业人士提到的那样,答案中建议的许多递归功能都会返回错误的结果。 (尝试使用上述片段的挑战的情况。)
也许某些棘手的方法,例如 .split('searchValue')。join('repenterValue') 或一些托管良好的功能给出相同的结果,但肯定的性能比<<代码>本机替换()/ polyfill替换()/ repleent() + regexp


polyfill分配的其他方法

幼稚,但支持较旧的浏览器 (最好避免)

例如,我们也可以通过不使用 object.defineproperty()使用我的旧幼稚分配方法:

if (!String.prototype.replaceAll) {
    String.prototype.replaceAll = function(search, replace) { // <-- Naive method for assignment
        // ... (Polyfill code Here)
    }
}

它应该很好地用于IE7+上的基本用途。
AS 在这里 @sebastian-simon解释了,这可以在更多情况下造成次要问题高级用途。例如:

for (var k in 'hi') console.log(k);
// 0
// 1
// replaceAll  <-- ?
完全值得信赖,但

实际上很重,我建议的选择有点乐观。就像我们信任环境一样(浏览器和 node.js ) -2021。另外,它是标准/著名,因此不需要任何特殊考虑。

但是,甚至可能会有一些较旧的浏览器一些意外的问题,而多填充仍然可以支持和解决更多可能的环境问题。因此,如果我们需要可能的最大支持,我们可以使用 polyfill库 like:

https:// polyfill.io/

专门用于替换

<script src="https://polyfill.io/v3/polyfill.min.js?features=String.prototype.replaceAll"></script>

Of course in 2021 the right answer is:

String.prototype.replaceAll()

console.log(
  'Change this and this for me'.replaceAll('this','that') // Normal case
);
console.log(
  'aaaaaa'.replaceAll('aa','a') // Challenged case
);

If you don't want to deal with replace() + RegExp.

But what if the browser is from before 2020?

In this case we need polyfill (forcing older browsers to support new features) (I think for a few years will be necessary).
I could not find a completely right method in answers. So I suggest this function that will be defined as a polyfill.

My suggested options for replaceAll polyfill:

replaceAll polyfill (with global-flag error) (more principled version)
if (!String.prototype.replaceAll) { // Check if the native function not exist
    Object.defineProperty(String.prototype, 'replaceAll', { // Define replaceAll as a prototype for (Mother/Any) String
        configurable: true, writable: true, enumerable: false, // Editable & non-enumerable property (As it should be)
        value: function(search, replace) { // Set the function by closest input names (For good info in consoles)
            return this.replace( // Using native String.prototype.replace()
                Object.prototype.toString.call(search) === '[object RegExp]' // IsRegExp?
                    ? search.global // Is the RegEx global?
                        ? search // So pass it
                        : function(){throw new TypeError('replaceAll called with a non-global RegExp argument')}() // If not throw an error
                    : RegExp(String(search).replace(/[.^$*+?()[{|\\]/g, "\\
amp;"), "g"), // Replace all reserved characters with '\' then make a global 'g' RegExp
                replace); // passing second argument
        }
    });
}
replaceAll polyfill (With handling global-flag missing by itself) (my first preference) - Why?
if (!String.prototype.replaceAll) { // Check if the native function not exist
    Object.defineProperty(String.prototype, 'replaceAll', { // Define replaceAll as a prototype for (Mother/Any) String
        configurable: true, writable: true, enumerable: false, // Editable & non-enumerable property (As it should be)
        value: function(search, replace) { // Set the function by closest input names (For good info in consoles)
            return this.replace( // Using native String.prototype.replace()
                Object.prototype.toString.call(search) === '[object RegExp]' // IsRegExp?
                    ? search.global // Is the RegEx global?
                        ? search // So pass it
                        : RegExp(search.source, /\/([a-z]*)$/.exec(search.toString())[1] + 'g') // If not, make a global clone from the RegEx
                    : RegExp(String(search).replace(/[.^$*+?()[{|\\]/g, "\\
amp;"), "g"), // Replace all reserved characters with '\' then make a global 'g' RegExp
                replace); // passing second argument
        }
    });
}
Minified (my first preference):
if(!String.prototype.replaceAll){Object.defineProperty(String.prototype,'replaceAll',{configurable:!0,writable:!0,enumerable:!1,value:function(search,replace){return this.replace(Object.prototype.toString.call(search)==='[object RegExp]'?search.global?search:RegExp(search.source,/\/([a-z]*)$/.exec(search.toString())[1]+'g'):RegExp(String(search).replace(/[.^$*+?()[{|\\]/g,"\\
amp;"),"g"),replace)}})}
Try it:

if(!String.prototype.replaceAll){Object.defineProperty(String.prototype,'replaceAll',{configurable:!0,writable:!0,enumerable:!1,value:function(search,replace){return this.replace(Object.prototype.toString.call(search)==='[object RegExp]'?search.global?search:RegExp(search.source,/\/([a-z]*)$/.exec(search.toString())[1]+'g'):RegExp(String(search).replace(/[.^$*+?()[{|\\]/g,"\\
amp;"),"g"),replace)}})}

console.log(
  'Change this and this for me'.replaceAll('this','that')
); // Change that and that for me

console.log(
  'aaaaaa'.replaceAll('aa','a')
); // aaa

console.log(
  '{} (*) (*) (RegEx) (*) (\*) (\\*) [reserved characters]'.replaceAll('(*)','X')
); // {} X X (RegEx) X X (\*) [reserved characters]

console.log(
  'How (replace) (XX) with $1?'.replaceAll(/(xx)/gi,'$1')
); // How (replace) ($1) with $1?

console.log(
  'Here is some numbers 1234567890 1000000 123123.'.replaceAll(/\d+/g,'***')
); // Here is some numbers *** *** *** and need to be replaced.

console.log(
  'Remove numbers under 233: 236   229  711   200   5'.replaceAll(/\d+/g, function(m) {
    return parseFloat(m) < 233 ? '' : m
  })
); // Remove numbers under 233: 236     711

console.log(
  'null'.replaceAll(null,'x')
); // x


// The difference between My first preference and the original:
// Now in 2022 with browsers > 2020 it should throw an error (But possible it be changed in future)

//   console.log(
//      'xyz ABC abc ABC abc xyz'.replaceAll(/abc/i,'')
//   );

// Browsers < 2020:
// xyz     xyz
// Browsers > 2020
// TypeError: String.prototype.replaceAll called with a non-global RegExp

Browser support:

The result is the same as the native replaceAll in case of the first argument input is:
null, undefined, Object, Function, Date, ... , RegExp, Number, String, ...

Ref: 22.1.3.19 String.prototype.replaceAll ( searchValue, replaceValue)
+ RegExp Syntax

Important note: As some professionals mention it, many of recursive functions that suggested in answers, will return the wrong result. (Try them with the challenged case of the above snippet.)
Maybe some tricky methods like .split('searchValue').join('replaceValue') or some well managed functions give same result, but definitely with much lower performance than native replaceAll() / polyfill replaceAll() / replace() + RegExp


Other methods of polyfill assignment

Naive, but supports even older browsers (be better to avoid)

For example, we can support IE7+ too, by not using Object.defineProperty() and using my old naive assignment method:

if (!String.prototype.replaceAll) {
    String.prototype.replaceAll = function(search, replace) { // <-- Naive method for assignment
        // ... (Polyfill code Here)
    }
}

And it should work well for basic uses on IE7+.
But as here @sebastian-simon explained about, that can make secondary problems in case of more advanced uses. E.g.:

for (var k in 'hi') console.log(k);
// 0
// 1
// replaceAll  <-- ?
Fully trustable, but heavy

In fact, my suggested option is a little optimistic. Like we trusted the environment (browser and Node.js), it is definitely for around 2012-2021. Also it is a standard/famous one, so it does not require any special consideration.

But there can be even older browsers or some unexpected problems, and polyfills still can support and solve more possible environment problems. So in case we need the maximum support that is possible, we can use polyfill libraries like:

https://polyfill.io/

Specially for replaceAll:

<script src="https://polyfill.io/v3/polyfill.min.js?features=String.prototype.replaceAll"></script>
深府石板幽径 2025-02-19 03:22:18
function replaceAll(str, find, replace) {
  var i = str.indexOf(find);
  if (i > -1){
    str = str.replace(find, replace); 
    i = i + replace.length;
    var st2 = str.substring(i);
    if(st2.indexOf(find) > -1){
      str = str.substring(0,i) + replaceAll(st2, find, replace);
    }       
  }
  return str;
}
function replaceAll(str, find, replace) {
  var i = str.indexOf(find);
  if (i > -1){
    str = str.replace(find, replace); 
    i = i + replace.length;
    var st2 = str.substring(i);
    if(st2.indexOf(find) > -1){
      str = str.substring(0,i) + replaceAll(st2, find, replace);
    }       
  }
  return str;
}
独闯女儿国 2025-02-19 03:22:18

我喜欢这种方法(看起来更干净):

text = text.replace(new RegExp("cat","g"), "dog"); 

I like this method (it looks a little cleaner):

text = text.replace(new RegExp("cat","g"), "dog"); 
ι不睡觉的鱼゛ 2025-02-19 03:22:18
while (str.indexOf('abc') !== -1)
{
    str = str.replace('abc', '');
}
while (str.indexOf('abc') !== -1)
{
    str = str.replace('abc', '');
}
皓月长歌 2025-02-19 03:22:18

截至2020年8月,有一个第4阶段提案 向eCmascript添加 preplaceall 方法 string

现在,它得到了 Chrome 85+,Edge 85+,Firefox 77+,Safari 13.1+的支持。

用法与 方法:

String.prototype.replaceAll(searchValue, replaceValue)

以下是一个示例用法:

'Test abc test test abc test.'.replaceAll('abc', 'foo'); // -> 'Test foo test test foo test.'

它在,但存在多填充:

v8 实验标志后面的引擎 - Harmony-string-Replaceall
v8网站上了解更多信息。

As of August 2020 there is a Stage 4 proposal to ECMAScript that adds the replaceAll method to String.

It's now supported in Chrome 85+, Edge 85+, Firefox 77+, Safari 13.1+.

The usage is the same as the replace method:

String.prototype.replaceAll(searchValue, replaceValue)

Here's an example usage:

'Test abc test test abc test.'.replaceAll('abc', 'foo'); // -> 'Test foo test test foo test.'

It's supported in most modern browsers, but there exist polyfills:

It is supported in the V8 engine behind an experimental flag --harmony-string-replaceall.
Read more on the V8 website.

所有深爱都是秘密 2025-02-19 03:22:18

如果字符串包含类似的模式,例如 abccc ,您可以使用以下方式:

str.replace(/abc(\s|$)/g, "")

If the string contains a similar pattern like abccc, you can use this:

str.replace(/abc(\s|$)/g, "")
故事还在继续 2025-02-19 03:22:18

以前的答案太复杂了。只需使用 这样的功能:

str.replace(/your_regex_pattern/g, replacement_string);

示例:

var str = "Test abc test test abc test test test abc test test abc";

var res = str.replace(/[abc]+/g, "");

console.log(res);

The previous answers are way too complicated. Just use the replace function like this:

str.replace(/your_regex_pattern/g, replacement_string);

Example:

var str = "Test abc test test abc test test test abc test test abc";

var res = str.replace(/[abc]+/g, "");

console.log(res);

可是我不能没有你 2025-02-19 03:22:18

经过几次试验和大量失败,我发现以下功能在浏览器兼容性和易用性时似乎是最好的全能功能。这是我发现的旧浏览器的唯一工作解决方案。 (是的,即使旧的浏览器灰心并过时,一些旧应用程序仍然大量使用浏览器(例如old visual basic 6 applications或 excel .xlsm宏带有表单。)

无论如何,这就是简单的函数。

function replaceAll(str, match, replacement){
   return str.split(match).join(replacement);
}

After several trials and a lot of fails, I found that the below function seems to be the best all-rounder when it comes to browser compatibility and ease of use. This is the only working solution for older browsers that I found. (Yes, even though old browser are discouraged and outdated, some legacy applications still make heavy use of OLE browsers (such as old Visual Basic 6 applications or Excel .xlsm macros with forms.)

Anyway, here's the simple function.

function replaceAll(str, match, replacement){
   return str.split(match).join(replacement);
}
酒中人 2025-02-19 03:22:18

尽管人们提到了对正则的使用,但是如果您想替换文本,无论文本情况如何,都有更好的方法。像大写或小写。使用以下语法:

// Consider the below example
originalString.replace(/stringToBeReplaced/gi, '');

// The output will be all the occurrences removed irrespective of casing.

您可以参考详细示例

Although people have mentioned the use of regex, there's a better approach if you want to replace the text irrespective of the case of the text. Like uppercase or lowercase. Use the below syntax:

// Consider the below example
originalString.replace(/stringToBeReplaced/gi, '');

// The output will be all the occurrences removed irrespective of casing.

You can refer to the detailed example here.

来世叙缘 2025-02-19 03:22:18

如果您试图确保即使在替换之后即使您要寻找的字符串也不存在,则需要使用循环。

例如:

var str = 'test aabcbc';
str = str.replace(/abc/g, '');

完成后,您仍然会有“测试ABC”!

解决此问题的最简单循环是:

var str = 'test aabcbc';
while (str != str.replace(/abc/g, '')){
   str.replace(/abc/g, '');
}

但是,每个周期都会两次运行替换。也许(有被投票的风险)可以组合起来,以稍微有效但可读性较低:

var str = 'test aabcbc';
while (str != (str = str.replace(/abc/g, ''))){}
// alert(str); alerts 'test '!

这在寻找重复的字符串时可能特别有用。
例如,如果我们有“ a ,, b”,我们希望删除所有重复的逗号。
[在那种情况下,可以做。重置(/,+/g,','),但是在某个时候,正则是复杂的,足够慢到足以循环。]

If you are trying to ensure that the string you are looking for won't exist even after the replacement, you need to use a loop.

For example:

var str = 'test aabcbc';
str = str.replace(/abc/g, '');

When complete, you will still have 'test abc'!

The simplest loop to solve this would be:

var str = 'test aabcbc';
while (str != str.replace(/abc/g, '')){
   str.replace(/abc/g, '');
}

But that runs the replacement twice for each cycle. Perhaps (at risk of being voted down) that can be combined for a slightly more efficient but less readable form:

var str = 'test aabcbc';
while (str != (str = str.replace(/abc/g, ''))){}
// alert(str); alerts 'test '!

This can be particularly useful when looking for duplicate strings.
For example, if we have 'a,,,b' and we wish to remove all duplicate commas.
[In that case, one could do .replace(/,+/g,','), but at some point the regex gets complex and slow enough to loop instead.]

碍人泪离人颜 2025-02-19 03:22:18

我的实施,非常自我解释

function replaceAll(string, token, newtoken) {
    if(token!=newtoken)
    while(string.indexOf(token) > -1) {
        string = string.replace(token, newtoken);
    }
    return string;
}

My implementation, very self explanatory

function replaceAll(string, token, newtoken) {
    if(token!=newtoken)
    while(string.indexOf(token) > -1) {
        string = string.replace(token, newtoken);
    }
    return string;
}
假情假意假温柔 2025-02-19 03:22:18

您可以简单地使用以下方法

/**
 * Replace all the occerencess of $find by $replace in $originalString
 * @param  {originalString} input - Raw string.
 * @param  {find} input - Target key word or regex that need to be replaced.
 * @param  {replace} input - Replacement key word
 * @return {String}       Output string
 */
function replaceAll(originalString, find, replace) {
  return originalString.replace(new RegExp(find, 'g'), replace);
};

You can simply use below method

/**
 * Replace all the occerencess of $find by $replace in $originalString
 * @param  {originalString} input - Raw string.
 * @param  {find} input - Target key word or regex that need to be replaced.
 * @param  {replace} input - Replacement key word
 * @return {String}       Output string
 */
function replaceAll(originalString, find, replace) {
  return originalString.replace(new RegExp(find, 'g'), replace);
};
野鹿林 2025-02-19 03:22:18

以下功能对我有用:

String.prototype.replaceAllOccurence = function(str1, str2, ignore)
{
    return this.replace(new RegExp(str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\\
amp;"),(ignore?"gi":"g")),(typeof(str2)=="string")?str2.replace(/\$/g,"$$"):str2);
} ;

现在调用这样的函数:

"you could be a Project Manager someday, if you work like this.".replaceAllOccurence ("you", "I");

只需将此代码复制并粘贴到浏览器控制台中进行测试即可。

The following function works for me:

String.prototype.replaceAllOccurence = function(str1, str2, ignore)
{
    return this.replace(new RegExp(str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\\
amp;"),(ignore?"gi":"g")),(typeof(str2)=="string")?str2.replace(/\$/g,"$$"):str2);
} ;

Now call the functions like this:

"you could be a Project Manager someday, if you work like this.".replaceAllOccurence ("you", "I");

Simply copy and paste this code in your browser console to TEST.

叫思念不要吵 2025-02-19 03:22:18

我使用拆分和加入或此功能:

function replaceAll(text, busca, reemplaza) {
  while (text.toString().indexOf(busca) != -1)
    text = text.toString().replace(busca, reemplaza);
  return text;
}

I use split and join or this function:

function replaceAll(text, busca, reemplaza) {
  while (text.toString().indexOf(busca) != -1)
    text = text.toString().replace(busca, reemplaza);
  return text;
}
っ〆星空下的拥抱 2025-02-19 03:22:18

现在有一个完成的建议用于集成 string.string.prototype.replacealty.replaceall 进入官方规范。最终,开发人员不必为替换提出自己的实现 - 而是现代的JavaScript引擎将在本地支持它。

该提案在第4阶段,,意思是 一切都已完成,所有剩下的都用于浏览器开始实施它。

以下是实施详细信息:

根据当前的TC39共识, string.prototype.replaceall 在所有情况下与 string.prototype.replace 在所有情况下的行为相同, 以下两种情况:

  1. 如果 searchValue 是字符串, string.prototype.replace 仅替换了单个出现 searchValue ,而 string。 prototype.replaceall 替换 所有出现 searchValue (如 .split(searchValue)。 &amp;已使用适当的正则表达式)。
  2. 如果 searchValue 是一种非全球正则表达式, string.prototype.replace 替换单个匹配,而 string.string.prototype.replaceall 引发例外。这样做是为了避免缺乏全局旗(意味着“不替换全部”)与所谓的方法的名称(强烈建议“替换全部”)之间的固有混乱。

值得注意的是, string.protype.replaceall 行为就像 string.prototype.replace.replace 如果 searchValue 是全局正则表达式。

您可以看到一个规格符合的 polyfill 在这里

在受支持的环境中,以下片段将记录 foo-bar-baz ,而不会丢弃错误:

const str = 'foo bar baz';
console.log(
  str.replaceAll(' ', '-')
);

There is now a finished proposal for integrating String.prototype.replaceAll into the official specification. Eventually, developers will not have to come up with their own implementations for replaceAll - instead, modern JavaScript engines will support it natively.

The proposal is at stage 4, which means that everything is complete, and all that's left is for browsers to start implementing it.

It has shipped in the latest versions of Chrome, Firefox, and Safari.

Here are the implementation details:

Per the current TC39 consensus, String.prototype.replaceAll behaves identically to String.prototype.replace in all cases, except for the following two cases:

  1. If searchValue is a string, String.prototype.replace only replaces a single occurrence of the searchValue, whereas String.prototype.replaceAll replaces all occurrences of the searchValue (as if .split(searchValue).join(replaceValue) or a global & properly-escaped regular expression had been used).
  2. If searchValue is a non-global regular expression, String.prototype.replace replaces a single match, whereas String.prototype.replaceAll throws an exception. This is done to avoid the inherent confusion between the lack of a global flag (which implies "do NOT replace all") and the name of the method being called (which strongly suggests "replace all").

Notably, String.prototype.replaceAll behaves just like String.prototype.replace if searchValue is a global regular expression.

You can see a specification-compliant polyfill here.

In supported environments, the following snippet will log foo-bar-baz, without throwing an error:

const str = 'foo bar baz';
console.log(
  str.replaceAll(' ', '-')
);

醉梦枕江山 2025-02-19 03:22:18

如果使用库是您的选择,那么您将获得带有库功能的测试和社区支持的好处。例如, string.js 库具有一个替换()函数,可实现您要寻找的内容:

// Include a reference to the string.js library and call it (for example) S.
str = S(str).replaceAll('abc', '').s;

If using a library is an option for you then you will get the benefits of the testing and community support that goes with a library function. For example, the string.js library has a replaceAll() function that does what you're looking for:

// Include a reference to the string.js library and call it (for example) S.
str = S(str).replaceAll('abc', '').s;
如歌彻婉言 2025-02-19 03:22:18

在我的应用程序中,我使用一个为此目的最强大的自定义功能,甚至在更简单的情况下包装 split/join 解决方案,在Chrome 60和Firefox 54中,它更快一点( jsben.ch )比其他解决方案。我的计算机运行Windows 7 64位。

优点是,此自定义功能可以同时使用字符串或字符同时处理许多替换,这对于某些应用程序可能是捷径。

像上述 split/join 解决方案一样,下面的解决方案没有任何逃生字符的问题,其方式与正则表达方法不同。

function replaceAll(s, find, repl, caseOff, byChar) {
    if (arguments.length<2)
        return false;
    var destDel = ! repl;       // If destDel delete all keys from target
    var isString = !! byChar;   // If byChar, replace set of characters
    if (typeof find !== typeof repl && ! destDel)
        return false;
    if (isString && (typeof find !== "string"))
        return false;

    if (! isString && (typeof find === "string")) {
        return s.split(find).join(destDel ? "" : repl);
    }

    if ((! isString) && (! Array.isArray(find) ||
        (! Array.isArray(repl) && ! destDel)))
        return false;

    // If destOne replace all strings/characters by just one element
    var destOne = destDel ? false : (repl.length === 1);

    // Generally source and destination should have the same size
    if (! destOne && ! destDel && find.length !== repl.length)
        return false

    var prox, sUp, findUp, i, done;
    if (caseOff)  { // Case insensitive

    // Working with uppercase keys and target
    sUp = s.toUpperCase();
    if (isString)
       findUp = find.toUpperCase()
    else
       findUp = find.map(function(el) {
                    return el.toUpperCase();
                });
    }
    else { // Case sensitive
        sUp = s;
        findUp = find.slice(); // Clone array/string
    }

    done = new Array(find.length); // Size: number of keys
    done.fill(null);

    var pos = 0;  // Initial position in target s
    var r = "";   // Initial result
    var aux, winner;
    while (pos < s.length) {       // Scanning the target
        prox  = Number.MAX_SAFE_INTEGER;
        winner = -1;  // No winner at the start
        for (i=0; i<findUp.length; i++) // Find next occurence for each string
            if (done[i]!==-1) { // Key still alive

                // Never search for the word/char or is over?
                if (done[i] === null || done[i] < pos) {
                    aux = sUp.indexOf(findUp[i], pos);
                    done[i] = aux;  // Save the next occurrence
                }
                else
                    aux = done[i]   // Restore the position of last search

                if (aux < prox && aux !== -1) { // If next occurrence is minimum
                    winner = i; // Save it
                    prox = aux;
                }
        } // Not done

        if (winner === -1) { // No matches forward
            r += s.slice(pos);
            break;
        } // No winner

        // Found the character or string key in the target

        i = winner;  // Restore the winner
        r += s.slice(pos, prox); // Update piece before the match

        // Append the replacement in target
        if (! destDel)
            r += repl[destOne ? 0 : i];
        pos = prox + (isString ? 1 : findUp[i].length); // Go after match
    }  // Loop

    return r; // Return the resulting string
}

文档如下:

 替换

 句法
 ======

      替换(s,查找,[repl,caseoff,bychar)

 参数
 ==========

   “ S”是更换的字符串目标。
   “查找”可以是字符串或字符串。
   “ repl”应该与“查找”或空的类型相同

  如果“查找”是字符串,则是一个简单的替代品
    所有“查找”出现在“ s”中的字符串“ repl”中

  如果“查找”是一个数组,它将替换“查找”中的每个字符串
    对于“ repl”数组中的相应字符串,这发生在“ S”中。
  替换规格是独立的:替换零件不能
  再次更换。


  如果“ repl”为空,则所有“查找”出现在“ s”中。
  如果“ repl”只有一个字符或元素,
      将替换为“ S”中的所有发生。

  如果替换是案例不敏感的,则“ caseoff”是正确的
       (默认为false)

  当更换基于字符集时,“ Bychar”是正确的。
  默认值为false

  如果“ bychar”,它将在“ find”中的所有字符中替换为“ s”
  “ repl”中相应字符的字符集
  一组字符

 返回
 ======

  该功能在替换后返回新字符串。
 

公平地说,我运行了基准测试没有参数测试。

这是我的测试集,使用node.js:

function l() {
    return console.log.apply(null, arguments);
}

var k = 0;
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
      ["ri", "nea"], ["do", "fa"]));  // 1
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
      ["ri", "nea"], ["do"])); // 2
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
      ["ri", "nea"])); // 3
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
     "aeiou", "", "", true)); // 4
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
      "aeiou", "a", "", true)); // 5
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
      "aeiou", "uoiea", "", true)); // 6
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
      "aeiou", "uoi", "", true)); // 7
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
      ["ri", "nea"], ["do", "fa", "leg"])); // 8
l(++k, replaceAll("BANANA IS A RIPE FRUIT HARVESTED NEAR THE RIVER",
      ["ri", "nea"], ["do", "fa"])); // 9
l(++k, replaceAll("BANANA IS A RIPE FRUIT HARVESTED NEAR THE RIVER",
      ["ri", "nea"], ["do", "fa"], true)); // 10
return;

和结果:

1'香蕉是浓缩的浓汤,多佛'
2'香蕉是多佛的浓汤收获'
3'香蕉是收获的pe果实'
4'BNN S RP frt hrvstd nr th rvr'
5'香蕉作为Rapa fraat Harvastad naar tha ravar'
6'Bununu是Ripo frait hurvostod nour tho rivor'
7 false
8个错误
9“香蕉是在河边收获的成熟水果”
10'香蕉是多佛(Dover)收获的浓汤'

In my applications, I use a custom function that is the most powerful for this purpose, and even wrapping the split/join solution in the simpler case, it is a little bit faster in Chrome 60 and Firefox 54 (JSBEN.CH) than other solutions. My computer runs Windows 7 64 bits.

The advantage is that this custom function can handle many substitutions at the same time using strings or characters, which can be a shortcut for some applications.

Like the above split/join solution, the solution below doesn't have any problems with escape characters, differently than the regular expression approach.

function replaceAll(s, find, repl, caseOff, byChar) {
    if (arguments.length<2)
        return false;
    var destDel = ! repl;       // If destDel delete all keys from target
    var isString = !! byChar;   // If byChar, replace set of characters
    if (typeof find !== typeof repl && ! destDel)
        return false;
    if (isString && (typeof find !== "string"))
        return false;

    if (! isString && (typeof find === "string")) {
        return s.split(find).join(destDel ? "" : repl);
    }

    if ((! isString) && (! Array.isArray(find) ||
        (! Array.isArray(repl) && ! destDel)))
        return false;

    // If destOne replace all strings/characters by just one element
    var destOne = destDel ? false : (repl.length === 1);

    // Generally source and destination should have the same size
    if (! destOne && ! destDel && find.length !== repl.length)
        return false

    var prox, sUp, findUp, i, done;
    if (caseOff)  { // Case insensitive

    // Working with uppercase keys and target
    sUp = s.toUpperCase();
    if (isString)
       findUp = find.toUpperCase()
    else
       findUp = find.map(function(el) {
                    return el.toUpperCase();
                });
    }
    else { // Case sensitive
        sUp = s;
        findUp = find.slice(); // Clone array/string
    }

    done = new Array(find.length); // Size: number of keys
    done.fill(null);

    var pos = 0;  // Initial position in target s
    var r = "";   // Initial result
    var aux, winner;
    while (pos < s.length) {       // Scanning the target
        prox  = Number.MAX_SAFE_INTEGER;
        winner = -1;  // No winner at the start
        for (i=0; i<findUp.length; i++) // Find next occurence for each string
            if (done[i]!==-1) { // Key still alive

                // Never search for the word/char or is over?
                if (done[i] === null || done[i] < pos) {
                    aux = sUp.indexOf(findUp[i], pos);
                    done[i] = aux;  // Save the next occurrence
                }
                else
                    aux = done[i]   // Restore the position of last search

                if (aux < prox && aux !== -1) { // If next occurrence is minimum
                    winner = i; // Save it
                    prox = aux;
                }
        } // Not done

        if (winner === -1) { // No matches forward
            r += s.slice(pos);
            break;
        } // No winner

        // Found the character or string key in the target

        i = winner;  // Restore the winner
        r += s.slice(pos, prox); // Update piece before the match

        // Append the replacement in target
        if (! destDel)
            r += repl[destOne ? 0 : i];
        pos = prox + (isString ? 1 : findUp[i].length); // Go after match
    }  // Loop

    return r; // Return the resulting string
}

The documentation is below:

 replaceAll

 Syntax
 ======

      replaceAll(s, find, [repl, caseOff, byChar)

 Parameters
 ==========

   "s" is a string target of replacement.
   "find" can be a string or array of strings.
   "repl" should be the same type than "find" or empty

  If "find" is a string, it is a simple replacement for
    all "find" occurrences in "s" by string "repl"

  If "find" is an array, it will replaced each string in "find"
    that occurs in "s" for corresponding string in "repl" array.
  The replace specs are independent: A replacement part cannot
  be replaced again.


  If "repl" is empty all "find" occurrences in "s" will be deleted.
  If "repl" has only one character or element,
      all occurrences in "s" will be replaced for that one.

  "caseOff" is true if replacement is case insensitive
       (default is FALSE)

  "byChar" is true when replacement is based on set of characters.
  Default is false

  If "byChar", it will be replaced in "s" all characters in "find"
  set of characters for corresponding character in "repl"
  set of characters

 Return
 ======

  The function returns the new string after the replacement.

To be fair, I ran the benchmark with no parameter test.

Here is my test set, using Node.js:

function l() {
    return console.log.apply(null, arguments);
}

var k = 0;
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
      ["ri", "nea"], ["do", "fa"]));  // 1
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
      ["ri", "nea"], ["do"])); // 2
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
      ["ri", "nea"])); // 3
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
     "aeiou", "", "", true)); // 4
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
      "aeiou", "a", "", true)); // 5
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
      "aeiou", "uoiea", "", true)); // 6
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
      "aeiou", "uoi", "", true)); // 7
l(++k, replaceAll("banana is a ripe fruit harvested near the river",
      ["ri", "nea"], ["do", "fa", "leg"])); // 8
l(++k, replaceAll("BANANA IS A RIPE FRUIT HARVESTED NEAR THE RIVER",
      ["ri", "nea"], ["do", "fa"])); // 9
l(++k, replaceAll("BANANA IS A RIPE FRUIT HARVESTED NEAR THE RIVER",
      ["ri", "nea"], ["do", "fa"], true)); // 10
return;

And the results:

1 'banana is a dope fruit harvested far the dover'
2 'banana is a dope fruit harvested dor the dover'
3 'banana is a pe fruit harvested r the ver'
4 'bnn s rp frt hrvstd nr th rvr'
5 'banana as a rapa fraat harvastad naar tha ravar'
6 'bununu is u ripo frait hurvostod nour tho rivor'
7 false
8 false
9 'BANANA IS A RIPE FRUIT HARVESTED NEAR THE RIVER'
10 'BANANA IS A doPE FRUIT HARVESTED faR THE doVER'

凉世弥音 2025-02-19 03:22:18

在2019年11月,将新功能添加到JavaScript, string.prototype.replaceall()

目前,它仅支持在此处阅读

In November 2019, a new feature is added to the JavaScript, string.prototype.replaceAll().

Currently it's only supported with Babel, but maybe in the future it can be implemented in all the browsers. For more information, read here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文