усечь строку, но удалить середину строки вместо конца


Я придумал эту функцию, которая усекает заданную строку либо до заданного количества слов, либо до заданного количества символов, что короче. Затем, после того, как он отсекает все после ограничения количества символов или слов, он добавляет "..." к строке.

Как я могу удалить символы/слова из середины строки и заменить их на "..." вместо замены символов/слов в конце на "..."?

Вот мой код:

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 символов короче, так что произойдет усечение. Таким образом, "лиса перепрыгивает через ленивую собаку" будет удалена, а "..." будет добавлено.

Но, вместо этого, как я могу сделать так, чтобы половина ограничения символов приходилась на начало строки, а половина - на конец строки, а то, что удалено в середине, заменено на "..."? Итак, строка, которую я хочу вернуть в этом, первом, случае, будет такой: "quic...ленивый пес".

Author: irfan mir, 2013-06-01

3 answers

$text = 'the quick brown fox jumps over the lazy dog';
$textLength = strlen($text);
$maxChars = 16;

$result = substr_replace($text, '...', $maxChars/2, $textLength-$maxChars);

$результат теперь:

the quic...lazy dog
 22
Author: Ziarno, 2013-06-01 05:12:12

Это не изменит ввод, который короче $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;
}
 1
Author: crishoj, 2016-08-05 12:36:16

Вот что я в итоге использовал:

/**
 * 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));
}

Для моего варианта использования правая часть строки содержала больше полезной информации, поэтому этот метод смещен в сторону удаления символов из левой половины.

 0
Author: adean, 2016-05-22 18:11:47