$ snippet escape-regex
Escape a string for use in a regex
Turn user input like 'price (USD)' into a pattern that matches it literally, so a stray ( or . doesn't break or change your search.
/** Escape all regex metacharacters. */
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
/** Case-insensitive "find all" for a literal string. */
function findAll(text, needle, flags = "gi") {
return [...text.matchAll(new RegExp(escapeRegExp(needle), flags))].map(m => m.index);
}
/** Replace all occurrences of a literal string (older engines without replaceAll). */
function replaceLiteral(text, needle, replacement) {
return text.replace(new RegExp(escapeRegExp(needle), "g"), () => replacement);
}How it works
Building a RegExp from a string means every metacharacter in that string is interpreted: "a.b" matches "axb", "(" throws a syntax error, and "$1" in a replacement string becomes a back-reference. Escaping with a backslash before each special character makes the input literal. Passing a function as the replacement (as in replaceLiteral) sidesteps the $ replacement patterns too.
Gotchas
- A newer standard method,
RegExp.escape(), does this natively in the latest engines; the helper is a drop-in until you can rely on it. - You only need to escape when you build a pattern. To search for a plain string,
text.includes(needle)orindexOfis simpler and faster. -only needs escaping inside a character class; this helper is for use outside one. If you insert into[...], also escape-and^.
Ad slot