0

我正在使用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, other\r\n和 others \r,但是\n是最常见的。
  • 有时,如果最后有一个 HTML 实体(如&quot;(引号)),它会保留为&quot,因此它不是有效的 HTML。我怎样才能防止这种情况?
4

2 回答 2

1

首先分别用and或and替换<br />标签。<br />\n</p><p></div><div></p>\n<p></div>\n<div>

然后将 PHP 函数用于条形标签,它应该在每个应该有换行符的地方产生一个带有换行符的漂亮纯文本。

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

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

您可能希望在使用 @PeeHaa 建议的wordwrap之前使用 html_entity_decode 。

于 2012-06-23T23:09:17.920 回答
0

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

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

Windows 使用\r\n,*nix(包括 mac OS)使用\n,(非常)旧的 mac 使用\r。如果数据来自网络(例如文本区域),它将(/应该)始终是\r\n. 因为这是规范规定用户代理应该做的事情。

有时,如果最后有一个像“(引号)这样的 HTML 实体,它会保留为 ",因此它不是有效的 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.');
于 2012-06-23T23:09:09.427 回答