截断字符串,但删除字符串的中间而不是结束


truncate string, but remove middle of string instead of end

我想出了这个函数,它将给定的字符串截断为给定的单词数或给定的字符数,无论哪个更短。然后,在截断字符数或字数限制之后的所有内容后,它附加一个'…

如何从字符串中间删除字符/单词并将其替换为'…,而不是用"…"来替换结尾的字符/单词?

下面是我的代码:
function truncate($input, $maxWords, $maxChars){
    $words = preg_split('/'s+/', $input);
    $words = array_slice($words, 0, $maxWords);
    $words = array_reverse($words);
    $chars = 0;
    $truncated = array();
    while(count($words) > 0)
    {
        $fragment = trim(array_pop($words));
        $chars += strlen($fragment);
        if($chars > $maxChars){
            if(!$truncated){
                $truncated[]=substr($fragment, 0, $maxChars - $chars);
            }
            break;
        }
        $truncated[] = $fragment;
    }
    $result = implode($truncated, ' ');
    return $result . ($input == $result ? '' : '...');
}

例如,如果调用truncate('the quick brown fox jumps over the lazy dog', 8, 16);,则缩短16个字符,因此将发生截断。所以,"狐狸跳过懒狗"将被删除,"……'将被追加。

但是,相反,我如何让一半的字符限制来自字符串的开始,一半来自字符串的结束,并且在中间删除的内容替换为'…'?因此,在这种情况下,我希望返回的字符串应该是:'the quic…懒狗。"

$text = 'the quick brown fox jumps over the lazy dog';
$textLength = strlen($text);
$maxChars = 16;
$result = substr_replace($text, '...', $maxChars/2, $textLength-$maxChars);

$result现在是:

the quic...lazy dog

这不会改变比$maxChars短的输入,并考虑到替换...的长度:

function str_truncate_middle($text, $maxChars = 25, $filler = '...')
{
    $length = strlen($text);
    $fillerLength = strlen($filler);
    return ($length > $maxChars)
        ? substr_replace($text, $filler, ($maxChars - $fillerLength) / 2, $length - $maxChars + $fillerLength)
        : $text;
}

我最后用的是:

/**
 * Removes characters from the middle of the string to ensure it is no more
 * than $maxLength characters long.
 *
 * Removed characters are replaced with "..."
 *
 * This method will give priority to the right-hand side of the string when
 * data is truncated.
 *
 * @param $string
 * @param $maxLength
 * @return string
 */
function truncateMiddle($string, $maxLength)
{
    // Early exit if no truncation necessary
    if (strlen($string) <= $maxLength) return $string;
    $numRightChars = ceil($maxLength / 2);
    $numLeftChars = floor($maxLength / 2) - 3; // to accommodate the "..."
    return sprintf("%s...%s", substr($string, 0, $numLeftChars), substr($string, 0 - $numRightChars));
}

对于我的用例,字符串的右侧包含更多有用的信息,因此该方法倾向于从左侧取出字符。