2013-06-01 9 views
8

Wpadłem na tę funkcję, która obcina dany ciąg do podanej liczby słów lub podanej liczby znaków, co jest krótsze. Następnie, po odłożeniu wszystkiego po liczbie znaków lub limicie słów, dodaje łańcuch "...".przyciąć ciąg, ale usunąć środkową część ciągu zamiast końca

Jak usunąć znaki/słowa ze środka ciągu i zastąpić je "..." zamiast zastępowania znaków/słów na końcu "..."?

Oto mój kod:

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 ? '' : '...'); 
} 

Na przykład jeśli truncate('the quick brown fox jumps over the lazy dog', 8, 16); nazywa, 16 znaków jest krótszy, dzięki czemu jest obcięcie że nastąpi. Tak więc "lis przeskoczy leniwego psa" zostanie usunięty i "..." zostanie dołączony.

Ale zamiast tego, w jaki sposób uzyskać połowę limitu znaków, może pochodzić od początku łańcucha, a połowa od końca łańcucha, a to, co zostało usunięte w środku, zastąpione przez "..."? Tak więc, ciąg znaków, który chciałbym zwrócić w tym jednym przypadku: "szybki ... leniwy pies".

Odpowiedz

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

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

$ wynik jest teraz:

the quic...lazy dog 
+1

+1 proste i piękne. – Orangepill

+3

Wymaga 'if ($ textLength> $ maxChars)' – Petah

+1

Zwróć uwagę, że w wyniku tego łańcuch składa się z 19 znaków, mimo że $ maxChars ma wartość 16. – adean

0

Oto, co skończyło się przy użyciu:

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

Na moim przypadku obsługi po prawej stronie napisu zawierał więcej przydatnych informacji, dzięki czemu ta metoda jest tendencyjna do wybierania postaci z lewej strony.

1

To nie zmieni wejście który jest krótszy niż $maxChars i zabiera długość zastąpienia ... pod uwagę:

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; 
} 
Powiązane problemy