I got it to work using the following:
<?php
$html = preg_replace_callback("#<(h[2-3])>(.*?)</\\1>#", "retitle", $rsRecordset->getColumnVal("ChapterText",false));
function retitle($match) {
list($_unused, $h2, $title) = $match;
$id = strtolower(strtr($title, " .", "--"));
echo "<$h2><a href='#$id'>$title</a></$h2>";
}
?>
This also generates an id for each h2 and h3 heading so that it can be used as an anchor link.
Might be useful to someone else!