缩短句子并找到最近的点

时间:2013-08-08 00:56:53

标签: php replace tags substring

我正在写一篇博客,我需要一个显示帖子摘录的功能。 我现在正在使用子字符串检查文本是否超过503个字符。

但这通常会在HTML标签的中间和单词的中间剪切我的文本,所以我让页面的其余部分就像半边写的标签一样。

I.e:“text text text <strong>Another piece of te [...],页面的其余部分都很强大,直到遇到新的强端标记。

我尝试从帖子中删除一些元素,但取消格式化我的文字。

我该如何说“好吧,文字是980个字符,在503处切换+到达最后一个点(。)或完成标记所需的任何其他内容。

按照我当前的代码:

<?php
  $testo_preview = preg_replace("/<img[^>]+\>/i", ' ', $valore->testo);
  $testo_preview = preg_replace("/<a[^>]+>/i", '<a>', $testo_preview);
  $testo_preview = preg_replace("/<span[^>]+>/i", '<span>', $testo_preview);
  $testo_preview = preg_replace("/<div[^>]+>/i", '', $testo_preview);
  $testo_preview = str_replace("</div>", '', $testo_preview);
  $testo_preview = str_replace("\n", '<br>', $testo_preview); 
?>

<?php if(strlen($testo_preview) >= 503): ?>

   <?= substr($testo_preview, 0, 503).' [...]' ?>

<?php else: ?>

   <?= $testo_preview; ?>

<?php endif; ?>

修改

我发现Pawel的回答是正常的,因为它实际上“已经到了”......

我不得不更改新的DOMDocument()部分,因为它搞乱了html口音(在意大利语中我们使用了一些口音,我需要它们留下来)。 我通过从Tigger获取部分代码将其转换为函数,因此我对你们两个都赞不绝口。 我提出了一个简单的功能:

function cleanCut($cutAt, $str){
        $next_dot = strpos($str, '.', $cutAt);
        if ($next_dot !== false){
            // text after default cutoff contains a dot so we need to extend the cutoff
            $preview_text = substr($str, 0, $next_dot + 1);
            // HTML Cleanup
            $preview_text = strip_tags($preview_text);
            $preview_text = str_replace("\n", '<br>', $preview_text);           
        } else {
            $preview_text = $str;
        }

        return $preview_text;
    }

它工作得很好。只是有时候没有达到目的(当有一个长链接时)但它可以没问题。 现在,正如您从函数中看到的那样,我尝试将\n替换为<br>,这是我真正想要的唯一标记,但它不起作用。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

如果我没有错,你可以暂时忽略标签。找到您需要的最后一个时间段,然后清理打开的标签。 所以一种方法是: 1.在503个字符后找到点的位置。如果没有找到,则显示整个文本,否则为该点的子串。我们将使用offset来strpos。 2.清理HTML以关闭所有打开的标签。 3.由于DOMDocument输出完整的html文档,我们需要删除多余的文档。

示例:

$max_length = 16;
$full_text  = "<b>Lorem ****. Impsum ****. That's already too long.</b>";
$next_dot   = strpos($full_text, '.', $max_length);

if ($next_dot !== false)
{
    // text after default cutoff contains a dot so we need to extend the cutoff
    $preview_text = substr($full_text, 0, $next_dot + 1); +1 so that the last dot is in
    // HTML Cleanup
    $doc = new DOMDocument();
    $doc->loadHTML("$preview_text");
    $preview_text = $doc->saveHTML();
    $preview_text = preg_replace('/(.*)<body>|(<\/body>.*)/ism', '', $preview_text);
} else {
    $preview_text = $full_text;
}

echo $preview_text;

它有点幼稚,它几乎没有明显的问题,但是a。它就足够了或b。你将能够自己改进它。哦,然后c。你问更多问题:)

答案 1 :(得分:1)

此函数将在某一点或之后干净地剪切字符串并删除所有HTML标记。 &#8230;是“...”的HTML代码,作为单个字符。

// strips HTML tags and return a clean word cut at a certain point
// or just after it.
function cleanCut($cutAt, $str) {
    $tmp = strip_tags($str);
    $tmp = explode(' ',$tmp);
    foreach($tmp as $k => $v) {
        $cleanStr .= $v.' ';
        if (strlen($cleanStr) >= $cutAt) {
            return trim($cleanStr).'&#8230;';
        }
    }
    // and it case it is a short string
    return $cleanStr;
}