Вариант с
String.prototype.match
<!doctype html>
<html>
<head><style>body { font: 120% sans-serif; }</style></head>
<body>
<script>
// функция, выдающая строку и объект с данными о позиции цветного текста
function parse(string) {
var match;
var spans = [], index = 0, text = [], length;
while(match = string.match(/(\[color=([^\]]+)\])(.*?)(\[\/color\])/s)) {
index += match.index;
text.push(string.slice(0, match.index) + match[3]);
length = match[0].length - match[1].length - match[4].length;
spans.push({
start: index,
end: index + length,
color: match[2]
});
index += length;
string = string.slice(match.index + match[0].length);
}
text.push(string);
return {
text: text.join(""),
spans
};
}
// пример, проверка
function stringify({ text, spans }) {
return spans.reduce((string, { start, end, color }, index, data) => {
string.push(
`<mark style="color: ${color};">${text.slice(start, end)}</mark>`
);
string.push(
(index + 1) in data ?
text.slice(end, data[index + 1].start) :
text.slice(end)
);
return string;
}, [text.slice(0, 0 in spans ? spans[0].start : Infinity)]).join("");
}
var r = parse("Оооочень большая строка текста, [color=red]выделенный текст[/color], еще всякий текст текст текст [color=green]еще выделенный текст[/color]! Ну и тд.");
document.body.innerHTML = `<pre>${JSON.stringify(r, null, "\t")}</pre>` + stringify(r);
</script>
</body>
</html>