>>393
my $attr = qr/\w+=(?:(?:(')|(")|([^>]))(?:(?(2)[^']*)(?(3)[^"]*)(?(4)[^\s>]*))(?:(?(2)')(?(3)"))\s*)?/;
my $amp = qr/&(?!(?:(?:\#\d+)|(?:\#x[a-f\d]+)|(?:\w+));)/i;
s/(<\/?\w+\s*(?:$attr)*>)|(<)|(>)|(")|($amp)/
$1 and $1 or $5 and '<' or $6 and '>' or $7 and '"' or $8 and '&'
/xge;

Perlで書いてみたけど、どこか穴があるかも。