Trim 字,但如果找到则停在 html 元素的末尾

Trim words but stop at end of html element if found

此函数非常有用,但是如果找到 html 元素,它会在第 45 个字符计数处停止,这会破坏 html 元素。我怎样才能破例呢?我在猜测某种正则表达式,但不确定在这种情况下什么是最好的。

public function fts_custom_trim_words( $text, $num_words = 45, $more ) {
    ! empty( $num_words ) && 0 !== $num_words ? $more = __( '...' ) : '';
    $text = nl2br( $text );
    $text = strip_shortcodes( $text );
    // Add tags that you don't want stripped.
    $text        = strip_tags( $text, '<strong><br><em><i><a>' );
    $words_array = preg_split( "/[\n\r\t ]+/", $text, $num_words + 1, PREG_SPLIT_NO_EMPTY );
    $sep         = ' ';
    if ( count( $words_array ) > $num_words ) {
        array_pop( $words_array );
        $text_string = implode( $sep, $words_array );
        $text        = $text_string . $more;
    } else {
        $text = implode( $sep, $words_array );
    }

    return wpautop( $text );
}

现在它会破坏这样的东西....

@aeocreative 和我在萨拉索塔杂志 "Home of the Year" 颁奖​​典礼上!我为

您有两个选择:

1) 使用 PHP stript_tags()(简单选项) 这将 return 纯文本,字符串中的任何标签将不再起作用(即 <a>, <strong>, <li> 等。实现看起来像:

$text = strip_tags($text);

2) 在这里使用@Chris Harrison 的建议:PHP limit text string NOT including html tags?

此选项会保留标签,但需要您重新构建更复杂的函数。

更新:

这可能不是您要查找的内容,但我创建了一个简单的解决方案,将字符串分成多个块,然后检查每个块。它不如选项 2 精确,但需要维护的代码少得多。

function truncate($string, $maxChars) {
    // Explode input string on a character
    $stringParts = explode(' ', $string);
    $finalString = '';
    $charCount = 0;
    foreach ($stringParts as $part) {
        if ($charCount <= $maxChars) {
            $charCount += strlen(strip_tags($part));
            $finalString .= (' ' . $part);
        } else {
            return $finalString;
        }
    }
}

这可能有效,未经测试,但它应该有效,并且按照您的要求进行...

第一个是截断@字符数

<?php

function truncate_by_characters ( $s, $l = 45, $e = '...' )
{
    $sl = strlen ( $s );

    $ns = 0;

    $cr = 0;

    $rs = '';

    preg_match_all ( '/<[^>]*>[^<]+<\/[^>]*>|<(?!\/)[^>]*>/', $s, $m, PREG_OFFSET_CAPTURE | PREG_SET_ORDER );

    foreach ( $m as $v )
    {
        if ( ( $v[0][1] - $ns ) >= $l )
        {
            break;
        }

        $ss = substr ( $s, $ns, ( $v[0][1] - $ns ) );

        $cr += strlen ( $ss );

        $rs .= $ss . $v[0][0];

        $ns = ( $v[0][1] + strlen ( $v[0][0] ) );
    }

    if ( $cr < $l )
    {
        if ( ( $ns + ( $l - $cr ) ) > $sl )
        {
            $ts = substr ( $s, $ns, ( $sl - $ns ) );
        }
        else
        {
            $ts = substr ( $s, $ns, ( $l - $cr ) );
        }

        for ( $x = ( strlen ( $ts ) - 1 ); $x >= 0; $x -= 1 )
        {
            $z = array ( "\t", "\r", "\n", " ", "[=10=]", "\x0B" );

            if ( in_array ( $ts[$x], $z ) )
            {
                $rs .= substr ( $ts, 0, $x );

                break;
            }
        }
    }

    return $rs . $e;
}

$truncate_text = 'This <img src="" alt=""> function works great however if a <a href="http://.com/page.html?test=1">html element</a> is found it will stop where the 45th character count is no matter what, which breaks the html element. How can I make an exception for this? I\'m guessing some kind of regex but not sure what is best in this case.';

//$truncate_text = 'This function works great however if a html element is found it will stop where the 45th character count is no matter what, which breaks the html element. How can I make an exception for this? I\'m guessing some kind of regex but not sure what is best in this case.';

$truncate_characters = 45;

$truncate_ending = '...';

echo truncate_by_characters ( $truncate_text, $truncate_characters, $truncate_ending );

?>

注意:上面的函数有效,但是下面的函数目前不会产生任何结果。

第二个是截断@字数

<?php

function truncate_by_words ( $s, $l = 45, $e = '...' )
{
    $sl = strlen ( $s );

    $ns = 0;

    $tw = 0;

    $rs = '';

    preg_match_all ( '/<[^>]*>[^<]+<\/[^>]*>|<(?!\/)[^>]*>/', $s, $m, PREG_OFFSET_CAPTURE | PREG_SET_ORDER );

    foreach ( $m as $v )
    {
        $ss = substr ( $s, $ns, ( $v[0][1] - $ns ) );

        $wf = str_word_count ( $ss, 2 );

        $wc = count ( $wf );

        if ( ( $tw + $wc ) >= $l )
        {
            $mw = 1;

            foreach ( $wf AS $wp => $wv )
            {
                if ( ( $tw + $mw++ ) == $l )
                {
                    $ss = substr ( $s, $ns, ( $wp - $ns ) );

                    $rs .= $ss . $wv;

                    $ns = ( $wp + strlen ( $wv ) );

                    $tw = $l;

                    break;
                }
            }
        }

        $tw += $wc;

        $rs .= $ss . $v[0][0];

        $ns = ( $v[0][1] + strlen ( $v[0][0] ) );
    }

    if ( $tw < $l )
    {
        $ss = substr ( $s, $ns, ( $sl - $ns ) );

        $wf = str_word_count ( $ss, 2 );

        $wc = count ( $wf );

        if ( ( $tw + $wc ) <= $l )
        {
            $rs .= $ss;
        }
        else
        {
            $mw = 1;

            foreach ( $wf AS $wp => $wv )
            {
                if ( ( $tw + $mw++ ) == $l )
                {
                    $ss = substr ( $ss, 0, $wp );

                    $rs .= $ss . $wv;

                    break;
                }
            }
        }
    }

    return $rs . $e;
}

$truncate_text = 'This <img src="" alt=""> function works great however if a <a href="http://.com/page.html?test=1">html element</a> is found it will stop where the 45th character count is no matter what, which breaks the html element. How can I make an exception for this? I\'m guessing some kind of regex but not sure what is best in this case.';

//$truncate_text = 'This function works great however if a html element is found it will stop where the 45th character count is no matter what, which breaks the html element. How can I make an exception for this? I\'m guessing some kind of regex but not sure what is best in this case.';

$truncate_words = 35;

$truncate_ending = '...';

echo truncate_by_words ( $truncate_text, $truncate_words, $truncate_ending );

?>