|
| 1 | +--- |
| 2 | +title: RegExp.escape() |
| 3 | +slug: Web/JavaScript/Reference/Global_Objects/RegExp/escape |
| 4 | +page-type: javascript-static-method |
| 5 | +browser-compat: javascript.builtins.RegExp.escape |
| 6 | +--- |
| 7 | + |
| 8 | +{{JSRef}} |
| 9 | + |
| 10 | +The **`RegExp.escape()`** static method [escapes](/en-US/docs/Web/JavaScript/Reference/Regular_expressions#escape_sequences) any potential regex syntax characters in a string, and returns a new string that can be safely used as a [literal](/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Literal_character) pattern for the {{jsxref("RegExp/RegExp", "RegExp()")}} constructor. |
| 11 | + |
| 12 | +When dynamically creating a {{jsxref("RegExp")}} with user-provided content, consider using this function to sanitize the input (unless the input is actually intended to contain regex syntax). In addition, don't try to re-implement its functionality by, for example, using {{jsxref("String.prototype.replaceAll()")}} to insert a `\` before all syntax characters. `RegExp.escape()` is designed to use escape sequences that work in many more edge cases/contexts than hand-crafted code is likely to achieve. |
| 13 | + |
| 14 | +## Syntax |
| 15 | + |
| 16 | +```js-nolint |
| 17 | +RegExp.escape(string) |
| 18 | +``` |
| 19 | + |
| 20 | +### Parameters |
| 21 | + |
| 22 | +- `string` |
| 23 | + - : The string to escape. |
| 24 | + |
| 25 | +### Return value |
| 26 | + |
| 27 | +A new string that can be safely used as a literal pattern for the {{jsxref("RegExp/RegExp", "RegExp()")}} constructor. Namely, the following things in the input string are replaced: |
| 28 | + |
| 29 | +- The first character of the string, if it's either a decimal digit (0–9) or ASCII letter (a–z, A–Z), is escaped using the `\x` [character escape](/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Character_escape) syntax. For example, `RegExp.escape("foo")` returns `"\\x66oo"` (here and after, the two backslashes in a string literal denote a single backslash character). This step ensures that if this escaped string is embedded into a bigger pattern where it's immediately preceded by `\1`, `\x0`, `\u000`, etc., the leading character doesn't get interpreted as part of the escape sequence. |
| 30 | +- Regex [syntax characters](/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Literal_character#description), including `^`, `$`, `\`, `.`, `*`, `+`, `?`, `(`, `)`, `[`, `]`, `{`, `}`, and `|`, as well as the `/` delimiter, are escaped by inserting a `\` character before them. For example, `RegExp.escape("foo.bar")` returns `"\\x66oo\\.bar"`, and `RegExp.escape("(foo)")` returns `"\\(foo\\)"`. |
| 31 | +- Other punctuators, including `,`, `-`, `=`, `<`, `>`, `#`, `&`, `!`, `%`, `:`, `;`, `@`, `~`, `'`, `` ` ``, and `"`, are escaped using the `\x` syntax. For example, `RegExp.escape("foo-bar")` returns `"\\x66oo\\x2dbar"`. These characters cannot be escaped by prefixing with `\` because, for example, `/foo\-bar/u` is a syntax error. |
| 32 | +- The characters with their own [character escape](/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Character_escape) sequences: `\f` (U+000C FORM FEED), `\n` (U+000A LINE FEED), `\r` (U+000D CARRIAGE RETURN), `\t` (U+0009 CHARACTER TABULATION), and `\v` (U+000B LINE TABULATION), are replaced with their escape sequences. For example, `RegExp.escape("foo\nbar")` returns `"\\x66oo\\nbar"`. |
| 33 | +- The space character is escaped as `"\\x20"`. |
| 34 | +- Other non-ASCII [line break and white space characters](/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#white_space) are replaced with one or two `\uXXXX` escape sequences representing their UTF-16 code units. For example, `RegExp.escape("foo\u2028bar")` returns `"\\x66oo\\u2028bar"`. |
| 35 | +- [Lone surrogates](/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#utf-16_characters_unicode_code_points_and_grapheme_clusters) are replaced with their `\uXXXX` escape sequences. For example, `RegExp.escape("foo\uD800bar")` returns `"\\x66oo\\ud800bar"`. |
| 36 | + |
| 37 | +### Exceptions |
| 38 | + |
| 39 | +- {{jsxref("TypeError")}} |
| 40 | + - : Thrown if `string` is not a string. |
| 41 | + |
| 42 | +## Examples |
| 43 | + |
| 44 | +### Using RegExp.escape() |
| 45 | + |
| 46 | +The following examples demonstrate various inputs and outputs for the `RegExp.escape()` method. |
| 47 | + |
| 48 | +```js |
| 49 | +RegExp.escape("Buy it. use it. break it. fix it."); |
| 50 | +// "\\x42uy\\x20it\\.\\x20use\\x20it\\.\\x20break\\x20it\\.\\x20fix\\x20it\\." |
| 51 | +RegExp.escape("foo.bar"); // "\\x66oo\\.bar" |
| 52 | +RegExp.escape("foo-bar"); // "\\x66oo\\x2dbar" |
| 53 | +RegExp.escape("foo\nbar"); // "\\x66oo\\nbar" |
| 54 | +RegExp.escape("foo\uD800bar"); // "\\x66oo\\ud800bar" |
| 55 | +RegExp.escape("foo\u2028bar"); // "\\x66oo\\u2028bar" |
| 56 | +``` |
| 57 | + |
| 58 | +### Using RegExp.escape() with the RegExp constructor |
| 59 | + |
| 60 | +The primary use case of `RegExp.escape()` is when you want to embed a string into a bigger regex pattern, and you want to ensure that the string is treated as a literal pattern, not as a regex syntax. Consider the following naïve example that replaces URLs: |
| 61 | + |
| 62 | +```js |
| 63 | +function removeDomain(text, domain) { |
| 64 | + return text.replace(new RegExp(`https?://${domain}(?=/)`, "g"), ""); |
| 65 | +} |
| 66 | + |
| 67 | +const input = |
| 68 | + "Consider using [RegExp.escape()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/escape) to escape special characters in a string."; |
| 69 | +const domain = "developer.mozilla.org"; |
| 70 | +console.log(removeDomain(input, domain)); |
| 71 | +// Consider using [RegExp.escape()](/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/escape) to escape special characters in a string. |
| 72 | +``` |
| 73 | + |
| 74 | +Inserting the `domain` above results in the regular expression literal `https?://developer.mozilla.org(?=/)`, where the "." character is a regex [wildcard](/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Wildcard) character. This means the string will match the string with any character in place of the ".", such as `developer-mozilla-org`. Therefore, it would incorrectly also change the following text: |
| 75 | + |
| 76 | +```js |
| 77 | +const input = |
| 78 | + "This is not an MDN link: https://developer-mozilla.org/, be careful!"; |
| 79 | +const domain = "developer.mozilla.org"; |
| 80 | +console.log(removeDomain(input, domain)); |
| 81 | +// This is not an MDN link: /, be careful! |
| 82 | +``` |
| 83 | + |
| 84 | +To fix this, we can use `RegExp.escape()` to ensure that any user input is treated as a literal pattern: |
| 85 | + |
| 86 | +```js |
| 87 | +function removeDomain(text, domain) { |
| 88 | + return text.replace( |
| 89 | + new RegExp(`https?://${RegExp.escape(domain)}(?=/)`, "g"), |
| 90 | + "", |
| 91 | + ); |
| 92 | +} |
| 93 | +``` |
| 94 | + |
| 95 | +Now this function will do exactly what we intend to, and will not transform `developer-mozilla.org` URLs. |
| 96 | + |
| 97 | +## Specifications |
| 98 | + |
| 99 | +{{Specifications}} |
| 100 | + |
| 101 | +## Browser compatibility |
| 102 | + |
| 103 | +{{Compat}} |
| 104 | + |
| 105 | +## See also |
| 106 | + |
| 107 | +- [Polyfill of `RegExp.escape` in `core-js`](https://github.com/zloirock/core-js#regexp-escaping) |
| 108 | +- {{jsxref("RegExp")}} |
0 commit comments