Very short snippet: PHP, tagliare a parole, contando i caratteri

Come già visto in Very short snippet: PHP word cut è più gradevole spezzare un testo a “parole”, in quanto si evita di tagliare una parola. C’è comunque chi preferisce tagliare contando i caratteri, in quanto rende i “tagli” più omogenei e simili tra loro, nonostante il forte rischio di tagliare una parola, mozzandola di netto! Inoltre bisogna sempre considerare che, fatta eccezzione per casi particolari, i Font non sono proporzionali e di conseguenza la parola “WWW” può occupare uno spazio orizzontale in pixel differente da “Wii”.
Allo stesso modo quando si contano le parole si può incorrere in situazioni paraddosali, generando evidenti differenze tra i testi che si sìvoglione spezzare. Ad esempio la frase: “a tu per tu” contiene quattro parole, esattamente come “Washington, la casa bianca”. Tuttavia, risulta evidente che l’ultima frase è visibilmente più “lunga”, in pixel.
Una possibile soluzione al problema è una funzione ibrido, che tenga conto quindi sia della lunghezza dei caratteri, sia del “taglio” a fine parola:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
 * Taglia una stringa per parole contanto i caratteri
 * In questa versione non vengono "contati" gli spazi
 * decommentare la riga in caso si vuole un taglio
 * esatto a carattere
 *
 * @author  =undo=
 * @date  2009-09-11
 *
 * @param (string) $c   Stringa da tagliere
 * @param (int)    $l   Numero di caratteri massimo
 * @param (string) $e   Stringa da appendere, default "[...]"
 * @return
 */

function word_cut_for_chars($c, $l, $e = "[...]") {
    if( strlen($c) > $l) {
        $a = explode(' ',$c);
        $s = 0;
        $r = "";
        for($i=0; $i<count($a); $i++) {
            $s += strlen($a[$i]);
            // $s += ( strlen($a[$i]) + 1);  // conta anche "lo spazio"
            if($s > $l ) return ($r . $e);
            $r .= $a[$i] . " ";
        }
    }
    return $c;
}
  • http://rabenblog.eraben.com Raben

    Piccolo errore nel titolo “contanto” ;)
    semre utilissimi i tuoi post! ;)

  • http://www.undolog.com Giovambattista Fazioli

    @Raben: Ecco cosa succede a fare le ore piccole :D Thanks

  • http://www.miserve.com Santino Bivacqua

    Ciao io invece utilizzo da tempo questa soluzione:

    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    function getShortDescription($text, $len, $textContinue = '...') {
      $text = strip_tags($text);//Elimino eventuali tag HTML
      if (strlen($text) <= (int)$len) {
        return $text;
      } else {
        $text = wordwrap($text, (int)$len, "___end___");
        return  substr($text, 0, -strlen(stristr($text,"___end___"))) . $textContinue;
      }
    }

    Bisognerebbe misurare il tempo impiegato da entrambi (magari con stringhe lunghissime) e capire quale soluzione sia migliore.

  • http://www.undolog.com Giovambattista Fazioli

    @Santino Bivacqua: interessante… in giro ne ho trovato anche una variante che usa explode(), in pratica, al posto del tuo stristr():

    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function wordCut($text, $limit, $msg){
        if (strlen($text) > $limit){
            $txt1 = wordwrap($text, $limit, '[cut]');
            $txt2 = explode('[cut]', $txt1);
            $ourTxt = $txt2[0];
            $finalTxt = $ourTxt.$msg;
        }else{
            $finalTxt = $text;
        }
        return $finalTxt;
    }
  • http://www.miserve.com Santino Bivacqua

    @Giovambattista Fazioli:
    Infatti il principio di funzionamento è molto simile :)
    Ora sono tre le soluzioni da provare per verificare (in testi lunghi) quale più veloce :)