Вы можете использовать регулярное выражение с отрицательным прогнозом, который проверит, что нет закрытия >
после потенциального совпадения, без предшествующего <
:
let s = "this is a <sample> string with <some> special words. this <is another> one";
let result = s.replace(/is(?![^<>]*>)/g, "*$&*");
console.log(result);
Обратите внимание, что эта логика также будет соответствовать третьему "есть" в этом логе c.