修剪单词,但在发现HTML元素的末端停止



此函数非常有效,但是,如果发现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( "/[nrt ]+/", $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和我在《萨拉索塔》杂志"年度最佳之家"奖中!我为@tracee_murphy of&lt;拍照Ahref =" https://www.instagram.com/trade" ...

这可能有效,未经测试,但应该起作用,并做您问的事情...

这个第一个是截断 @字符数

<?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", " ", "", "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 );
?>

您有两个选项:

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

$text = strip_tags($text);

2)在这里使用@chris harrison的建议:php限制文本字符串不包括html标签?

此选项保留标签,但需要您重建功能更为复杂。

更新:

这可能不是您想要的,但是我创建了一个简单的解决方案,将字符串分解成块,然后检查每个块。它不像选项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;
        }
    }
}

最新更新