{"id":13451736,"url":"https://github.com/tc39/proposal-string-replaceall","last_synced_at":"2025-03-23T19:32:28.043Z","repository":{"id":66007520,"uuid":"110955464","full_name":"tc39/proposal-string-replaceall","owner":"tc39","description":"ECMAScript proposal: String.prototype.replaceAll","archived":true,"fork":false,"pushed_at":"2021-02-19T12:32:31.000Z","size":81,"stargazers_count":253,"open_issues_count":0,"forks_count":17,"subscribers_count":23,"default_branch":"master","last_synced_at":"2024-10-28T18:15:52.422Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://tc39.es/proposal-string-replaceall/","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tc39.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-11-16T10:07:20.000Z","updated_at":"2024-06-27T13:02:08.000Z","dependencies_parsed_at":"2023-03-14T13:15:31.152Z","dependency_job_id":null,"html_url":"https://github.com/tc39/proposal-string-replaceall","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tc39%2Fproposal-string-replaceall","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tc39%2Fproposal-string-replaceall/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tc39%2Fproposal-string-replaceall/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tc39%2Fproposal-string-replaceall/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tc39","download_url":"https://codeload.github.com/tc39/proposal-string-replaceall/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245158100,"owners_count":20570118,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T07:01:00.844Z","updated_at":"2025-03-23T19:32:27.721Z","avatar_url":"https://github.com/tc39.png","language":"HTML","readme":"# `String.prototype.replaceAll` proposal\n\n## Status\n\nChampion: Mathias Bynens (Google, @mathiasbynens).\n\nThis proposal is at stage 4 of [the TC39 process](https://tc39.es/process-document/), and is scheduled to be included in ES2021.\n\n## Motivation\n\n(Also see [our TL;DR explainer](https://v8.dev/features/string-replaceall).)\n\nCurrently there is no way to replace all instances of a substring in a string without use of a global regexp.\n`String.prototype.replace` only affects the first occurrence when used with a string argument. There is a lot of evidence that developers are trying to do this in JS — see the [StackOverflow question](https://stackoverflow.com/q/1144783/96656) with thousands of votes.\n\nCurrently the most common way of achieving this is to use a global regexp.\n\n```js\nconst queryString = 'q=query+string+parameters';\nconst withSpaces = queryString.replace(/\\+/g, ' ');\n```\n\nThis approach has the downside of requiring special RegExp characters to be escaped — note the escaped `'+'`.\n\nAn alternate solution is to combine `String#split` with `Array#join`:\n\n```js\nconst queryString = 'q=query+string+parameters';\nconst withSpaces = queryString.split('+').join(' ');\n```\n\nThis approach avoids any escaping but comes with the overhead of splitting the string into an array of parts only to glue it back together.\n\n## Proposed solution\n\nWe propose the addition of a new method to the String prototype - `replaceAll`. This would give developers a straight-forward way to accomplish this common, basic operation.\n\n```js\nconst queryString = 'q=query+string+parameters';\nconst withSpaces = queryString.replaceAll('+', ' ');\n```\n\nIt also removes the need to escape special regexp characters (note the unescaped `'+'`).\n\n## High-level API\n\nThe proposed signature is the same as the existing `String.prototype.replace` method:\n\n```js\nString.prototype.replaceAll(searchValue, replaceValue)\n```\n\nPer the current TC39 consensus, `String.prototype.replaceAll` behaves identically to `String.prototype.replace` in all cases, **except** for the following two cases:\n\n1. 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 \u0026 properly-escaped regular expression had been used).\n1. 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\").\n\nNotably, `String.prototype.replaceAll` behaves just like `String.prototype.replace` if `searchValue` is a global regular expression.\n\n## Comparison to other languages\n\n* Java has [`replace`](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#replace-java.lang.CharSequence-java.lang.CharSequence-), accepting a `CharSequence` and replacing all occurrences. Java also has [`replaceAll`](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#replaceAll-java.lang.String-java.lang.String-) which accepts a regex as the search term (requiring the user to escape special regex characters), again replacing all occurrences by default.\n* Python [`replace`](https://www.tutorialspoint.com/python/string_replace.htm) replaces all occurrences, but accepts an optional param to limit the number of replacements.\n* PHP has [`str_replace`](http://php.net/manual/en/function.str-replace.php) which has an optional limit parameter like python.\n* Ruby has [`gsub`](https://ruby-doc.org/core/String.html#method-i-gsub), accepting a regexp or string, but also accepts a callback block and a hash of match -\u003e replacement pairs.\n\n## FAQ\n\n### What are the main benefits?\n\nA simplified API for this common use-case that does not require RegExp knowledge. A way to global-replace strings without having to escape RegExp syntax characters. Possibly improved optimization potential on the VM side.\n\n### What about adding a `limit` parameter to `replace` instead?\n\nA: This is an awkward interface — because the default limit is 1, the user would have to know how many occurrences already exist, or use something like Infinity.\n\n### What happens if `searchValue` is the empty string?\n\n`String.prototype.replaceAll` follows the precedent set by `String.prototype.replace`, and returns the input string with the replacement value spliced in between every UCS-2/UTF-16 code unit.\n\n```js\n'x'.replace('', '_');\n// → '_x'\n'xxx'.replace(/(?:)/g, '_');\n// → '_x_x_x_'\n'xxx'.replaceAll('', '_');\n// → '_x_x_x_'\n```\n\n## TC39 meeting notes\n\n- [November 2017](https://tc39.es/tc39-notes/2017-11_nov-28.html#10ih-stringprototypereplaceall-for-stage-1)\n- [March 2019](https://github.com/tc39/tc39-notes/blob/master/meetings/2019-03/mar-26.md#stringprototypereplaceall-for-stage-2)\n- [July 2019](https://github.com/tc39/tc39-notes/blob/master/meetings/2019-07/july-24.md#stringprototypereplaceall)\n- [June 2020](https://github.com/tc39/notes/blob/master/meetings/2020-06/june-2.md#stringprototypereplaceall-for-stage-4)\n\n## Specification\n\n- [Ecmarkup source](https://github.com/tc39/proposal-string-replaceall/blob/master/spec.html)\n- [HTML version](https://tc39.es/proposal-string-replaceall/)\n\n## Implementations\n\n- [SpiderMonkey](https://bugzilla.mozilla.org/show_bug.cgi?id=1540021), shipping in [Firefox 77](https://bugzilla.mozilla.org/show_bug.cgi?id=1608168)\n- [JavaScriptCore](https://bugs.webkit.org/show_bug.cgi?id=202471), shipping in [Safari 13.1](https://webkit.org/blog/10247/new-webkit-features-in-safari-13-1/#javascript-improvements)\n- [V8](https://bugs.chromium.org/p/v8/issues/detail?id=9801), shipping in Chrome 85\n- Polyfills:\n    - [core-js](https://github.com/zloirock/core-js#stringreplaceall)\n    - [es-shims](https://github.com/es-shims/String.prototype.replaceAll)\n","funding_links":[],"categories":["HTML","JavaScript regex evolution"],"sub_categories":["Regex processors, utilities, and more"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftc39%2Fproposal-string-replaceall","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftc39%2Fproposal-string-replaceall","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftc39%2Fproposal-string-replaceall/lists"}