JavaScript RegExp.escape() Method

JavaScript RegExp.escape() converts a string into text that you can safely place inside a regular expression. It treats characters such as ., *, +, ?, parentheses, brackets, and slashes as literal characters instead of pattern instructions.

Use this method when a search term, file name, product code, URL, or another value comes from a user or variable. It helps you create a dynamic regular expression without changing the intended meaning of that value.

RegExp.escape() prepares text for a regular expression pattern. It does not validate input, secure HTML, or replace normal application security checks.

Why RegExp.escape() Is Useful

A regular expression contains characters with special meanings. For example, the plus sign means “repeat the previous item one or more times.” If you place the text A+B directly inside new RegExp(), the pattern will not search for a literal plus sign.

RegExp.escape() returns an escaped string that keeps the input literal. You can then combine that string with your own trusted pattern syntax.

  • Search for user-entered text exactly as written.
  • Build find-and-replace tools with dynamic terms.
  • Highlight names, prices, product codes, or punctuation.
  • Add literal text to a larger regular expression.

JavaScript RegExp.escape() Syntax

Syntax:

// Escape a string before adding it to a pattern
RegExp.escape(string)

The method accepts one string and returns a new escaped string. It does not change the original value. Passing a non-string value throws a TypeError; JavaScript does not automatically convert numbers, objects, null, or undefined.

Example:

// These results are strings intended for RegExp()
RegExp.escape("A+B");        // "\x41\+B"
RegExp.escape("report.pdf"); // "\x72eport\.pdf"
RegExp.escape("price: $5");  // "\x70rice\x3a\x20\$5"

The output may look more detailed than expected. A leading ASCII letter or digit uses a hexadecimal escape, spaces become \x20, and some punctuation also uses hexadecimal escapes. These choices prevent escaped text from accidentally joining a preceding escape sequence in a larger pattern.

Searching for Literal Text

Escape only the variable part of a dynamic pattern. Keep the regular expression syntax that you control outside the method.

Example:

// Search for A+B literally and ignore letter case
const searchTerm = "A+B";
const pattern = new RegExp(RegExp.escape(searchTerm), "gi");

"A+B and A-B".match(pattern); // ["A+B"]

The following complete example accepts a search term, creates a case-insensitive global pattern, and reports every literal match. Try terms such as A+B, A-B, or ..

Example:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Literal Search with RegExp.escape()</title>
    <style>
        body {
            max-width: 700px;
            margin: 2rem auto;
            padding: 0 1rem;
            font-family: Arial, sans-serif;
            line-height: 1.6;
            color: #253545;
        }

        input,
        button {
            padding: 0.65rem;
            font: inherit;
        }

        input {
            width: min(100%, 320px);
        }

        button {
            color: #fff;
            background: #1769aa;
            border: 0;
            border-radius: 0.3rem;
            cursor: pointer;
        }

        #result {
            padding: 0.75rem;
            background: #f3f6f8;
        }
    </style>
</head>
<body>
    <h1>Find Literal Text</h1>
    <p id="source">Order A+B before A-B. A+B is the requested item.</p>

    <label for="search">Search term:</label>
    <input id="search" value="A+B">
    <button type="button" id="find">Find matches</button>

    <p id="result" aria-live="polite"></p>

    <script>
        // Search for the entered text without treating + or other characters as regex syntax.
        const source = document.querySelector('#source').textContent;
        const searchInput = document.querySelector('#search');
        const result = document.querySelector('#result');

        document.querySelector('#find').addEventListener('click', () => {
            if (typeof RegExp.escape !== 'function') {
                result.textContent = 'This browser does not support RegExp.escape().';
                return;
            }

            const term = searchInput.value;
            if (!term) {
                result.textContent = 'Enter a search term.';
                return;
            }

            const pattern = new RegExp(RegExp.escape(term), 'gi');
            const matches = source.match(pattern) ?? [];
            result.textContent = `Found ${matches.length} match(es): ${matches.join(', ')}`;
        });
    </script>
</body>
</html>

Highlighting Dynamic Text

A highlighting feature often needs to search for punctuation exactly as a user entered it. The next example escapes the search term and uses matchAll() to locate each result.

It creates mark elements with DOM methods instead of inserting a constructed HTML string. This keeps the source content as text and separates regex escaping from HTML handling.

Example:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Highlight Text with RegExp.escape()</title>
    <style>
        body {
            max-width: 700px;
            margin: 2rem auto;
            padding: 0 1rem;
            font-family: Arial, sans-serif;
            line-height: 1.6;
            color: #253545;
        }

        input,
        button {
            padding: 0.65rem;
            font: inherit;
        }

        button {
            color: #fff;
            background: #1769aa;
            border: 0;
            border-radius: 0.3rem;
            cursor: pointer;
        }

        #output {
            padding: 1rem;
            background: #f3f6f8;
        }

        mark {
            padding: 0.1rem;
            background: #ffe780;
        }
    </style>
</head>
<body>
    <h1>Highlight Literal Text</h1>
    <p>Riya paid $5.00, Ethan paid $7.50, and Olivia paid $5.00.</p>

    <label for="search">Highlight:</label>
    <input id="search" value="$5.00">
    <button type="button" id="highlight">Highlight text</button>

    <p id="output" aria-live="polite"></p>

    <script>
        // Build highlighted output with DOM nodes so the source remains plain text.
        const text = 'Riya paid $5.00, Ethan paid $7.50, and Olivia paid $5.00.';
        const searchInput = document.querySelector('#search');
        const output = document.querySelector('#output');

        function showHighlightedText(term) {
            output.replaceChildren();

            if (!term) {
                output.textContent = text;
                return;
            }

            const pattern = new RegExp(RegExp.escape(term), 'gi');
            let previousIndex = 0;

            for (const match of text.matchAll(pattern)) {
                output.append(text.slice(previousIndex, match.index));

                const mark = document.createElement('mark');
                mark.textContent = match[0];
                output.append(mark);

                previousIndex = match.index + match[0].length;
            }

            output.append(text.slice(previousIndex));
        }

        document.querySelector('#highlight').addEventListener('click', () => {
            if (typeof RegExp.escape !== 'function') {
                output.textContent = 'This browser does not support RegExp.escape().';
                return;
            }

            showHighlightedText(searchInput.value);
        });

        // Show the original text before the first search.
        output.textContent = text;
    </script>
</body>
</html>

Why Manual Escaping Is Unreliable

A common helper adds a backslash before familiar regex symbols. That approach may handle simple inputs, but it can miss other punctuators, whitespace, lone surrogates, and cases where the escaped result follows another escape sequence.

For example, prefixing a hyphen with a backslash can be invalid in some Unicode-aware pattern contexts. The standard method may use a hexadecimal escape instead. Use RegExp.escape() or a specification-compliant polyfill rather than maintaining a short replacement expression yourself.

Using RegExp.escape() in a Larger Pattern

You can combine escaped literal text with pattern syntax that your program controls. This example matches a complete product reference while keeping the variable code literal.

Example:

// Escape only the variable product code
const productCode = "AB-12.5";
const escapedCode = RegExp.escape(productCode);
const pattern = new RegExp("^Product:\\s+" + escapedCode + "$", "i");

pattern.test("Product: AB-12.5"); // true

Do not escape the entire pattern if you want anchors, groups, character classes, or quantifiers to keep their regex meaning. Escape only the values that should be matched as ordinary text.

Errors and Edge Cases

  • An empty string still represents an empty match.
  • A non-string argument throws TypeError.
  • The returned value is pattern source, not a RegExp object.
  • Flags such as g, i, m, or u belong in the RegExp constructor.
  • Escaping literal text does not fix an inefficient trusted pattern around it.

Example:

// Convert intentionally if your application accepts a number
const referenceNumber = 2048;
const escaped = RegExp.escape(String(referenceNumber));

new RegExp(escaped).test("Order 2048"); // true

Browser Support and Fallbacks

RegExp.escape() became broadly available across current major browsers in May 2025. Older browsers and older JavaScript runtimes may not provide it, so check your supported environments before using it without a fallback.

Example:

// Detect support before creating a dynamic pattern
if (typeof RegExp.escape === "function") {
  const pattern = new RegExp(RegExp.escape("A+B"));
  console.log(pattern.test("A+B")); // true
} else {
  console.log("Load a specification-compliant polyfill.");
}

For older environments, use a maintained polyfill that follows the ECMAScript algorithm. Avoid silently falling back to a short hand-written replacement because its output may differ in important edge cases.

Best Practices

  1. Use RegExp.escape() for variable text that must remain literal.
  2. Keep trusted regex syntax separate from escaped values.
  3. Pass a string deliberately instead of relying on automatic conversion.
  4. Choose flags according to the search behavior you need.
  5. Feature-detect the method when supporting older browsers.
  6. Handle HTML output separately when displaying or highlighting matches.

Conclusion

JavaScript RegExp.escape() provides a standard way to place literal text inside a dynamic regular expression. It handles regex symbols, punctuation, whitespace, and difficult escape boundaries more completely than a small custom helper. Escape the variable text, add only the trusted pattern syntax you need, and provide a compliant fallback when older environments are part of your support range.



Found This Page Useful? Share It!
Get the Latest Tutorials and Updates
Join us on Telegram