Lodash escapeRegExp with Already Escaped Strings

Lodash's _.escapeRegExp function is designed to sanitize strings by escaping special regular expression characters so they can be safely passed into a RegExp constructor. However, when passed a string that has already been escaped, the function does not detect existing escape sequences. Instead, it treats the existing escape characters—specifically the backslash (\)—as characters that must also be escaped, resulting in double-escaped strings that may break the intended regular expression pattern.

The Mechanism Behind _.escapeRegExp

The internal implementation of Lodash's _.escapeRegExp relies on a predefined list of regular expression characters that require escaping. This list includes:

^, $, \, ., *, +, ?, (, ), [, ], {, }, and |.

The function uses a standard replacement mechanism that matches any of these characters globally and prepends a backslash to them:

const reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
const escapeRegExp = (string) => string.replace(reRegExpChar, '\\$&');

Because the backslash character (\) is explicitly listed in reRegExpChar, _.escapeRegExp escapes every backslash it encounters without analyzing the surrounding syntax.

What Happens to Already Escaped Strings

If an input string contains an escaped regular expression sequence, the existing backslash is treated like any other special character and gets escaped again.

Consider the following example:

const _ = require('lodash');

// An already escaped string representing a literal dot
const preEscaped = '\\.'; 

const result = _.escapeRegExp(preEscaped);

console.log(result);
// Output: "\\\\\\."

In string representation:

  1. preEscaped contains two characters: \ and ..
  2. _.escapeRegExp processes the string character by character.
  3. The backslash \ matches the escape rule and becomes \\.
  4. The dot . matches the escape rule and becomes \..
  5. The combined result becomes \\\..

When passed to new RegExp(result), the regex engine interprets the first two backslashes as a literal backslash and the remaining \. as a literal dot. Instead of searching for just a dot (.), the pattern now searches for a backslash followed by a dot (\.).

Why Lodash Does Not Prevent Double-Escaping

Lodash avoids inspecting whether a backslash is part of an existing escape sequence for performance and predictability reasons. Parsing regular expression context—such as determining if a backslash itself is being escaped or if it is escaping an invalid character—adds significant complexity and execution overhead. The utility is intentionally designed under the assumption that the input is raw, unescaped text.

How to Prevent Double-Escaping Issues

To prevent unexpected behavior when dealing with regular expressions: