Не используйте для этого регулярное выражение, используйте (или напишите) парсер.
В следующем коде предполагается, что входная HTML-строка правильно сформирована (как вы сказали). Имейте в виду, что код сломается, если он обнаружит неверный ввод!
Если вы не уверены в правильности формы, вы можете попробовать PHP Tidy .
<?php
$html = '<tag>text "text"<tag attr="value"><!-- "text" --> text</tag> "text".';
echo html_escape_quotes($html);
/* Parses input HTML and escapes any literal double quotes
in the text content with ". Leaves comments alone. */
function html_escape_quotes($html)
{
$output = "";
$length = strlen($html);
$delim = "<";
$offset = 0;
while ($offset < $length) {
$tokpos = strpos($html, $delim, $offset);
if ($tokpos === false) $tokpos = $length;
$token = substr($html, $offset, $tokpos - $offset);
$offset = $tokpos;
if ($delim == "<") {
$token = str_replace('"', '"', $token);
$delim = substr($html, $offset, 4) == "<!--" ? "-->" : ">";
} else {
$delim = "<";
}
$output .= $token;
}
return $output;
}
?>