Вам нужно только простое регулярное выражение для этого.[+ любой символ +].И вам нужно только заменить содержимое в скобках, чтобы вы могли использовать () группы захвата для инкапсуляции изменяемого текста.
$new_text = preg_replace('/\[([^\]]+)\]/', '<span style="color:red;">$1</span>', $text);
РЕДАКТИРОВАТЬ:
Измененорегулярное выражение.Вместо того, чтобы сопоставлять все (что соответствует второму вхождению ]
), я сопоставляю все до первого вхождения ]
Еще лучше, поскольку @msg указывает в комментариях: регулярное выражение может быть: /\[(.*?)\]/