Чтобы решить проблему «полной остановки в теге», вы можете использовать нечто похожее на следующее, чтобы определить, находится ли остановка в теге:
$str_len = strlen($summary);
$pos_stop = strrpos($summary, '.');
$pos_tag_open = strrpos($summary, '<', -($str_len - $pos_stop));
$pos_tag_close = strpos($summary, '>', $pos_tag_open);
if (($pos_tag_open < $pos_stop) && ($pos_stop < $pos_tag_close)) {
// Inside tag! Search for the next nearest prior full-stop.
$pos_stop = strrpos($summary, '.', -($str_len - $pos_tag_open));
}
echo htmlentities(substr($summary, 0, $pos_stop + 1));
Очевидно, что этот код можно оптимизировать (и вытащить в свою собственную функцию), но вы поняли идею. У меня есть ощущение, что есть регулярное выражение, которое может справиться с этим более эффективно.
Edit:
Действительно, - это регулярное выражение, которое может сделать это, используя отрицательный прогноз:
$text = '<p>Abc def abc def abc def abc def. Abc def <img src="test.jpg" />abc</p>';
$count = preg_match_all("/\.(?!([^<]+)?>)/", $text, $arr, PREG_OFFSET_CAPTURE);
$offset = $arr[0][$count-1][1];
echo substr($text, 0, $offset + 1)."\n";
Это должно быть относительно эффективно, по крайней мере, по сравнению с truncate()
, который также использует preg_match для внутреннего использования.