01 · Before and afterThe pattern
// before: rescans the remaining input for every unclosed "<style"
text = html.replace(/<style[\s\S]*?<\/style>/gi, " ");
// after: one pass, bounded lookahead
for (let i = 0; i < html.length; ) {
const lt = html.indexOf("<", i);
if (lt === -1) { out += html.slice(i); break; }
out += html.slice(i, lt);
i = skipTag(html, lt, /* max tag length */ 2048); // jumps past a real </style>, never backtracks
}02 · Run it on your appThe check
Does any regex in your app run on raw HTML or text from outside users, and have you timed it on 1 MB of unclosed tags?
If the honest answer is no or not sure, this is worth a look before it reaches production.