【问题标题】:Making a preview of a long text预览长文本
【发布时间】:2012-06-25 18:48:04
【问题描述】:

我在 PHP 工作,我想创建一个函数,给定任意长度和高度的文本,返回相同文本的限制版本,最多 500 个字符和 10 行。

这是我目前所拥有的:

function preview($str)
{
    $partialPreview = explode("\n", substr($str, 0, 500));
    $partialPreviewHeight = count($partialPreview);
    $finalPreview = "";

    // if it has more than 10 lines
    if ($partialPreviewHeight > 10) {
        for ($i = 0; $i < 10; $i++) {
            $finalPreview .= $partialPreview[$i];
        }
    } else {
        $finalPreview = substr($str, 0, 500);
    }

    return $finalPreview;
}

我有两个问题:

  • 是否正确使用\n 来检测新的换行符?我知道有些 系统使用\n,其他\r\n和其他\r,但\n是最多的 常见。
  • 有时,如果有像&amp;quot;(引号)这样的HTML实体 最后,它保留为&amp;quot,因此它不是有效的HTML。如何 我可以防止这种情况发生吗?

【问题讨论】:

    标签: php html string text newline


    【解决方案1】:

    是否正确使用 \n 来检测新的换行符?我知道有些系统使用\n,其他的\r\n 和其他的\r,但是\n 是最常见的。

    这取决于数据的来源。不同的操作系统有不同的换行符。

    Windows 使用 \r\n,*nix(包括 mac OS)使用 \n,(非常)旧的 mac 使用 \r。如果数据来自网络(例如文本区域),它将(/应该)始终为\r\n。因为这就是the spec 状态user agents should do

    有时,如果最后有一个像“(引号)这样的 HTML 实体,它会保留为 &quot,因此它不是有效的 HTML。我该如何防止这种情况发生?

    在剪切文本之前,您可能需要将 html 实体转换回普通文本。根据您的需要使用htmlspecialchars_decode()html_entity_decode。现在您将不会遇到破坏实体的问题(如果需要,请不要忘记再次对其进行编码)。

    另一种选择是只打破空白字符上的文本,而不是硬字符限制。这样,您的“摘要”中只会包含整个单词。

    我创建了一个可以处理大多数问题的类。正如我已经说过的,当数据来自 textarea 时,它将始终为 \r\n,但为了能够解析其他换行符,我想出了如下内容(未经测试):

    class Preview
    {
        protected $maxCharacters;
        protected $maxLines;
        protected $encoding;
        protected $lineBreaks;
    
        public function __construct($maxCharacters = 500, $maxLines = 10, $encoding = 'UTF-8', array $lineBreaks = array("\r\n", "\r", "\n"))
        {
            $this->maxCharacters = $maxCharacters;
            $this->maxLines = $maxLines;
            $this->encoding = $encoding;
            $this->lineBreaks = $lineBreaks;
        }
    
        public function makePreview($text)
        {
            $text = $this->normalizeLinebreaks($text);
    
            // this prevents the breaking of the &quote; etc
            $text = html_entity_decode($text, ENT_QUOTES, $this->encoding);
    
            $text = $this->limitLines($text);
    
            if (mb_strlen($text, $this->encoding) > $this->maxCharacters) {
                $text = $this->limitCharacters($text);
            }
    
            return html_entity_decode($text, ENT_QUOTES, $this->encoding);
        }
    
        protected function normalizeLinebreaks($text)
        {
            return str_replace($lineBreaks, "\n", $text);
        }
    
        protected function limitLines($text)
        {
            $lines = explode("\n", $text);
            $limitedLines = array_slice($lines, 0, $this->maxLines);
    
            return implode("\n", $limitedLines);
        }
    
        protected function limitCharacters($text)
        {
            return substr($text, 0, $this->maxCharacters);
        }
    }
    
    $preview = new Preview();
    echo $preview->makePreview('Some text which will be turned into a preview.');
    

    【讨论】:

    • 谢谢你,非常完整的答案,非常感谢预览课程,它完美无缺!
    【解决方案2】:

    首先将&lt;br /&gt; 标记替换为&lt;br /&gt;\n&lt;/p&gt;&lt;p&gt; 或将&lt;/div&gt;&lt;div&gt; 分别替换为&lt;/p&gt;\n&lt;p&gt;&lt;/div&gt;\n&lt;div&gt;

    然后使用strip tags 的 PHP 函数,它应该会在每个应该有换行符的地方产生一个带有换行符的漂亮纯文本。

    然后您可以将\r\n 替换为\n 以保持一致性。只有在那之后,您才能提取所需的文本长度。

    您可能希望使用word wrapping 来实现您的 10 行目标。要使自动换行起作用,您需要为每行定义多个字符,并且自动换行会注意不影响单词中间。

    您可能希望在使用@PeeHaa 建议的自动换行之前使用html_entity_decode

    【讨论】:

      猜你喜欢
      • 2016-08-04
      • 2016-10-26
      • 1970-01-01
      • 2011-09-26
      • 2015-03-25
      • 1970-01-01
      • 2012-05-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多