PHP ограничивает текстовую строку, НЕ включающую html-теги?
Вот что у меня НЕ работает:
<?php
$string = 'I have a dog and his name is <a href="http://www.jackismydog.com">Jack</a> and I love him very much because he\'s my favorite dog in the whole wide world and nothing could make me not love him, I think.';
$limited = substr($string, 0, 100).'...';
echo $string;
?>
Я хочу ограничить ВИДИМЫЙ текст 100 символами, но использование substr()
также включает невидимый текст в ограничение (<a href="http://www.jackismydog.com">
и </a>
), которое занимает 41 из этих доступных 100 символов.
Есть ли способ ограничить текст так, чтобы слово "Джек" из ссылки было включено в ограничение, но не <a href="http://www.jackismydog.com">
или </a>
?
Редактировать: Я хочу сохранить ссылку в строке, просто не считайте ее длину по отношению к предел..
5 answers
Функция для усечения слов в HTML-коде:
//+ Jonas Raoni Soares Silva
//@ http://jsfromhell.com
function truncate($text, $length, $suffix = '…', $isHTML = true) {
$i = 0;
$simpleTags=array('br'=>true,'hr'=>true,'input'=>true,'image'=>true,'link'=>true,'meta'=>true);
$tags = array();
if($isHTML){
preg_match_all('/<[^>]+>([^<]*)/', $text, $m, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
foreach($m as $o){
if($o[0][1] - $i >= $length)
break;
$t = substr(strtok($o[0][0], " \t\n\r\0\x0B>"), 1);
// test if the tag is unpaired, then we mustn't save them
if($t[0] != '/' && (!isset($simpleTags[$t])))
$tags[] = $t;
elseif(end($tags) == substr($t, 1))
array_pop($tags);
$i += $o[1][1] - $o[0][1];
}
}
// output without closing tags
$output = substr($text, 0, $length = min(strlen($text), $length + $i));
// closing tags
$output2 = (count($tags = array_reverse($tags)) ? '</' . implode('></', $tags) . '>' : '');
// Find last space or HTML tag (solving problem with last space in HTML tag eg. <span class="new">)
$pos = (int)end(end(preg_split('/<.*>| /', $output, -1, PREG_SPLIT_OFFSET_CAPTURE)));
// Append closing tags to output
$output.=$output2;
// Get everything until last space
$one = substr($output, 0, $pos);
// Get the rest
$two = substr($output, $pos, (strlen($output) - $pos));
// Extract all tags from the last bit
preg_match_all('/<(.*?)>/s', $two, $tags);
// Add suffix if needed
if (strlen($text) > $length) { $one .= $suffix; }
// Re-attach tags
$output = $one . implode($tags[0]);
//added to remove unnecessary closure
$output = str_replace('</!-->','',$output);
return $output;
}
Самым простым способом было бы фактически проанализировать это в структуре DOM. Для этого вы можете использовать DOMDocument. Затем вы можете просто просмотреть элементы и внести любые изменения в контент.
Другой подход заключался бы в выполнении двухпроходного поиска по регулярному выражению и замене - сначала используйте регулярное выражение для поиска содержимого тегов, затем используйте регулярное выражение для замены содержимого сокращенным содержимым. Это может быть достигнуто с помощью ваших обычных функций preg_*.
Нелегко - вы, конечно, можете использовать strip_tags для удаления htmlиз строки, но кроме этого нет простого решения.
Если вы хотите ограничить текстовую часть, вам нужно разобрать ее и проверить ограничение самостоятельно. Самый простой способ - это:
if ( strlen(strip_tags($string)) > 100 )
{
// the url inside $url is too big
}
else
{
// the url inside $url fits
}
Вы могли бы попробовать это, сработало для меня, если в строке нет тегов $different будет иметь значение 0, что даст $stringsize ваше исходное значение 100
<?php
$string = 'I have a dog and his name is <a href="http://www.jackismydog.com">Jack</a> and I love him very much because he\'s my favorite dog in the whole wide world and nothing could make me not love him, I think.';
$stringall=strlen($string);
$striphtml = strip_tags($string);
$stringnohtml=strlen(striphtml);
$differ=($stringall-$stringnohtml);
$stringsize=($differ + 100);
$limited = substr($string, 0, $stringsize).'...';
echo $limited;
?>