demo · v136

Multi-term Highlighter

The headline use case from the TC39 proposal: take arbitrary user terms, escape each one, glue them into a single (a|b|c) alternation and highlight every match. With RegExp.escape, strings like C++, .NET, or a.b match literally instead of crashing or silently overmatching.

Probing RegExp.escape support…

naive: new RegExp(terms.join("|"))

safe: terms.map(RegExp.escape).join("|")

the code

function buildHighlighter(terms) {
  // Pre-136: hand-rolled escape, easy to get wrong on Unicode + leading digit cases.
  // 136+: one standard escape, no string-of-special-chars to maintain.
  const alt = terms
    .map(t => t.trim())
    .filter(Boolean)
    .map(RegExp.escape)
    .join("|");
  return new RegExp(alt, "gi");
}

document.body.innerHTML = document.body.innerHTML.replace(
  buildHighlighter(["C++", "$100", "(parens)", ".NET"]),
  m => `<mark>${m}</mark>`
);

why this angle

The single-input demo answers "does it escape?" — useful but minimal. The proposal's motivating example is exactly this: building one regex from many untrusted strings (autocomplete terms, tag filters, search-box history) and putting them through join("|"). That join has two traps: a stray ( or + can turn the whole alternation into a syntax error, while a valid pattern such as .NET|a.b quietly treats dots as "any character" and highlights the wrong text. The two presets above show both failure modes.

see also