beh ... con una sola espressione regolare no ne hai bisogno, sempre, due

con la prima estrai i tag e con la seconda estrai gli attributi ... non credo ci siano altri sistemi

per quanto riguarda il testo che non sta tra tag ... beh ... è un po una rottura :\

potresti provare con un qualcosa del tipo

preg_match_all('/>(.+?)</si', .....)

cosi, FORSE, funziona