Ciao spero di aver capito bene il problema,

mi sono trovato anche io nella tua situazione e quando ricevo dati da una text area o campo di testo utilizzo una funzione che man mano sto arricchendo.

invece dell'espressione regolare utilizzo str_replace() e non mi ha mai dato problemi con tag annidati

ti faccio un esempio molto stupido

Codice PHP:
$testo str_replace("[BOLD]","[b]",$programma); 
$testo str_replace("[/BOLD]","[/b]",$programma); 

per fare quello che ti serve potresti provare a fare così

Codice PHP:
$testo=str_replace("[span=$testo]","<span=$testo>",$testo);
$testo=str_replace("$testo[/span]","$testo</span>",$testo); 
spero di aver bene inteso quello che ti serve

Ciao