Причина, по которой вложенный блок не заменяется, заключается в том, что совпадение для [b] помещает позицию после [/ b]. Таким образом, все, что соответствует ((.) {1,}?), Игнорируется.
Можно написать рекурсивный синтаксический анализатор на стороне сервера - Perl использует qr //, и Ruby, вероятно, имеет что-то подобное.
Хотя вам не обязательно нужна настоящая рекурсивность. Вы можете использовать относительно простой цикл для равномерной обработки строки:
var s = '[b]hello[/b] [u]world[/u] [b]foo [u]to the[/u] bar[/b]';
var exptags = /[(b|u|i|s|center|code){1}]((.){1,}?)[/(1){1}]/ig;
while (s.match(exptags)) {
s = s.replace(exptags, "<$1>$2</$1>");
}
document.writeln('<div>' + s + '</div>'); // after
В этом случае он выполнит 2 прохода:
0: [b]hello[/b] [u]world[/u] [b]foo [u]to the[/u] bar[/b]
1: <b>hello</b> <u>world</u> <b>foo [u]to the[/u] bar</b>
2: <b>hello</b> <u>world</u> <b>foo <u>to the</u> bar</b>
Кроме того, несколько советов по очистке RegEx:
var exptags = /[(b|u|i|s|center|code)](.+?)[/(1)]/ig;
- {1} предполагается, когда нет других спецификаторов счетчика
- {1,} можно сократить до +