【问题标题】:Shorten sentence and find nearest dot缩短句子并找到最近的点
【发布时间】:2013-08-09 14:06:51
【问题描述】:

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

但这经常会在单词中间和 HTML 标记中间截断我的文本,所以我让页面的其余部分就像标记一半一样。

即:“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;
    }

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

【问题讨论】:

标签: php replace tags substring


【解决方案1】:

此函数将在某个点或紧随其后干净地剪切字符串,并删除所有 HTML 标记。 &amp;#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;
}

【讨论】:

    【解决方案2】:

    如果我没记错的话,你可以暂时忽略这些标签。找到您需要的最后一个时期,然后清理打开的标签。 所以一种方法是: 1.找到503个字符后点的位置。如果没有找到,则显示整个文本,否则为该点的子字符串。我们将使用偏移量到 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;
    

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

    【讨论】:

      猜你喜欢
      • 2016-04-08
      • 1970-01-01
      • 1970-01-01
      • 2013-06-08
      • 1970-01-01
      • 1970-01-01
      • 2012-09-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多