【问题标题】:Substr needs to account for HTML tagsSubstr 需要考虑 HTML 标签
【发布时间】:2014-09-04 10:24:33
【问题描述】:

我正在使用 Wordpress,并且正在输出帖子的 the_content(带有 HTML 格式)。我正在使用 substr 将其修剪为 500 个字符。

我想确保内容不会在单词中间被截断,所以我调整了它以使用 strpos 查找单词的结尾,这是此部分的代码,可以正常工作。

$post_content = get_the_content_with_formatting();
$post_trimmed = substr($post_content, 0, strpos($post_content, ' ', 500));
print $post_trimmed . '...';

问题是strpos 有时会在一个单词后截断,并破坏 HTML。例如,这是我得到的一些 HTML:

<p>
Marketing Assistant<br>
Marketing Executive<br>
<br... <="" p=""></br...></p>

我正试图准确解读发生了什么,但我认为我基本上需要使 strpos 不仅在单词的末尾修剪,而且在 HTML 标签的末尾,例如> 和 以确保它不会破坏 HTML。

你会怎么做呢?

【问题讨论】:

  • 因此,如果我有 2k 字文本并将其包装在 &lt;p&gt; 标记中,那么您将无法修剪我的任何文本,因为首先 &lt;p&gt; 会破坏 HTML 的其余部分或使您的 HTML 无效.为什么允许在可修剪的文本中使用 html?
  • 我认为这没问题,因为这是使用 Wordpress,它总是在使用换行符时在内容中添加

    ,但我明白你的意思,并且更喜欢更健壮的东西。我在可修剪的文本中使用 HTML,因为我需要设计的格式,但还需要能够设置字符数。

标签: php wordpress substr strpos


【解决方案1】:

这并不像您想象的那么简单。话虽如此,已经在另一个StackOverflow post 中讨论并概述了解决方案。

这是他们使用的函数,仅供参考:

function printTruncated($maxLength, $html, $isUtf8=true)
{
    $printedLength = 0;
    $position = 0;
    $tags = array();

    // For UTF-8, we need to count multibyte sequences as one character.
    $re = $isUtf8
        ? '{</?([a-z]+)[^>]*>|&#?[a-zA-Z0-9]+;|[\x80-\xFF][\x80-\xBF]*}'
        : '{</?([a-z]+)[^>]*>|&#?[a-zA-Z0-9]+;}';

    while ($printedLength < $maxLength && preg_match($re, $html, $match, PREG_OFFSET_CAPTURE, $position))
    {
        list($tag, $tagPosition) = $match[0];

        // Print text leading up to the tag.
        $str = substr($html, $position, $tagPosition - $position);
        if ($printedLength + strlen($str) > $maxLength)
        {
            print(substr($str, 0, $maxLength - $printedLength));
            $printedLength = $maxLength;
            break;
        }

        print($str);
        $printedLength += strlen($str);
        if ($printedLength >= $maxLength) break;

        if ($tag[0] == '&' || ord($tag) >= 0x80)
        {
            // Pass the entity or UTF-8 multibyte sequence through unchanged.
            print($tag);
            $printedLength++;
        }
        else
        {
            // Handle the tag.
            $tagName = $match[1][0];
            if ($tag[1] == '/')
            {
                // This is a closing tag.

                $openingTag = array_pop($tags);
                assert($openingTag == $tagName); // check that tags are properly nested.

                print($tag);
            }
            else if ($tag[strlen($tag) - 2] == '/')
            {
                // Self-closing tag.
                print($tag);
            }
            else
            {
                // Opening tag.
                print($tag);
                $tags[] = $tagName;
            }
        }

        // Continue after the tag.
        $position = $tagPosition + strlen($tag);
    }

    // Print any remaining text.
    if ($printedLength < $maxLength && $position < strlen($html))
        print(substr($html, $position, $maxLength - $printedLength));

    // Close any open tags.
    while (!empty($tags))
        printf('</%s>', array_pop($tags));
}


printTruncated(10, '<b>&lt;Hello&gt;</b> <img src="world.png" alt="" /> world!'); print("\n");

printTruncated(10, '<table><tr><td>Heck, </td><td>throw</td></tr><tr><td>in a</td><td>table</td></tr></table>'); print("\n");

printTruncated(10, "<em><b>Hello</b>&#20;w\xC3\xB8rld!</em>"); print("\n");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-11
    • 2011-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-29
    • 2011-09-03
    相关资源
    最近更新 更多