La única forma que se me ocurre es usar un bucle llamando a la función varias veces hasta que este cambiado.
El problema está en que una vez que ha sustituido una parte de la cadena no la vuelve a evaluar.
Puedes utilizar la función preg_match para ver si coincide alguna parte de la cadena con la expresión regular para saber cuando parar el bucle.
Algo así:
Código PHP:
Ver originaldo{
$txt=preg_replace('^\[color=(.*?)\](.*?)\[\/color\]^', '<font color="\\1">\\2</font>', $txt); while (preg_match('^\[color=(.*?)\](.*?)\[\/color\]^', '<font color="\\1">\\2</font>' )> 0)