2012-03-22 12 views
14

Sto cercando un modo per rendere il word-wrap in PHP un po 'più intelligente. Quindi non pre-interrompe le parole lunghe lasciando solo le piccole parole precedenti su una riga.Word-wrap più intelligente in PHP per parole lunghe?

Diciamo che ho questo (il testo reale è sempre completamente dinamico, questo è solo per mostrare):

wordwrap('hello! heeeeeeeeeeeeeeereisaverylongword', 25, '<br />', true); 

Questo uscite:

ciao!
heeeeeeeeeeeeeeereisavery
longword

See, lascia la piccola parola da solo sulla prima riga. Come posso ottenerlo ouput qualcosa di più simile a questo:

ciao! heeeeeeeeeeee
eeereisaverylongword

Quindi utilizza qualsiasi spazio disponibile su ogni riga. Ho provato diverse funzioni personalizzate, ma nessuna è stata efficace (o hanno alcuni inconvenienti).

+0

Sono appena arrivato da Google. Sono sorpreso che questo non funzioni. È un bug con la funzione integrata di PHP? Mi sembra che quando si imposta l'ultimo argomento su true, si dovrebbe utilizzare tutto lo spazio disponibile. Perché non dovrebbe farlo? –

+0

@Andrew Sì, non lo so. Puoi utilizzare il metodo CSS wrap o questo http://stackoverflow.com/questions/9815040/smarter-word-wrap-in-php-for-long-words/25273135#25273135 (se è per il web, ecc.). Pace – mowgli

risposta

15

ho avuto un andare alla funzione personalizzata per questo elegante wordwrap:

function smart_wordwrap($string, $width = 75, $break = "\n") { 
    // split on problem words over the line length 
    $pattern = sprintf('/([^ ]{%d,})/', $width); 
    $output = ''; 
    $words = preg_split($pattern, $string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); 

    foreach ($words as $word) { 
     if (false !== strpos($word, ' ')) { 
      // normal behaviour, rebuild the string 
      $output .= $word; 
     } else { 
      // work out how many characters would be on the current line 
      $wrapped = explode($break, wordwrap($output, $width, $break)); 
      $count = $width - (strlen(end($wrapped)) % $width); 

      // fill the current line and add a break 
      $output .= substr($word, 0, $count) . $break; 

      // wrap any remaining characters from the problem word 
      $output .= wordwrap(substr($word, $count), $width, $break, true); 
     } 
    } 

    // wrap the final output 
    return wordwrap($output, $width, $break); 
} 

$string = 'hello! too long here too long here too heeeeeeeeeeeeeereisaverylongword but these words are shorterrrrrrrrrrrrrrrrrrrr'; 
echo smart_wordwrap($string, 11) . "\n"; 

EDIT: individuato un paio di avvertimenti. Un avvertimento importante con questo (e anche con la funzione nativa) è la mancanza di supporto multibyte.

+0

Che cosa significa $ width = 75 impostato in modo esatto? – mowgli

+0

La firma della funzione è esattamente quella del wordwrap (senza il parametro break), quindi imposta una larghezza di avvolgimento predefinita di 75 caratteri. – cmbuckley

+0

niente, è solo i valori di default che sta usando. Nel caso non si fornisca il proprio di '11', verrà usato' 75'. – Eli

2

Questo dovrebbe fare il trucco ...

$word = "hello!" . wordwrap('heeeeeeeeeeeeeeereisaverylongword', 25, '<br />', true); 
echo $word; 
+0

Ho appena usato alcune parole di esempio. Nell'uso reale, il testo sarebbe completamente dinamico, quindi non potrei usarlo. – mowgli

+0

Non sono sicuro di come stai provando a farlo, ma perché non potresti cambiarlo dinamicamente? Usa le variabili per impostare il tuo testo –

+0

Cambia dinamicamente cosa? Il testo può essere qualsiasi cosa, qualsiasi lunghezza, qualsiasi numero di parole. Non so quale sarà la prima parola o qualsiasi parola;) – mowgli

5

È possibile utilizzare i CSS per raggiungere questo obiettivo.

word-wrap: break-word; 

Che spezzerà la parola per voi. Ecco un link per vederlo in azione:

http://www.css3.info/preview/word-wrap/

+3

Non sto rompendo le parole per un browser – mowgli

+0

questo non ha funzionato per me. L'ho provato su un tavolo. Ho applicato alcuni 'width' in stile e' word-wrap: break-word; ' –

+0

È 2014 e non funziona ancora su tutti i browser. A volte php ti copre il sedere. – Maelish

11

Come su

$string = "hello! heeeeeeeeeeeeeeereisaverylongword"; 
$break = 25; 

echo implode(PHP_EOL, str_split($string, $break)); 

quali uscite

hello! heeeeeeeeeeeeeeere                                       
isaverylongword 

str_split() converte la stringa in un array di $ rompere dimensioni pezzi.

implode() si unisce l'array di nuovo insieme come una stringa utilizzando la colla che in questo caso è un marcatore di fine linea (PHP_EOL) anche se potrebbe facilmente essere un '<br/>'

+0

dove va la parola avvolgimento? ;) – mowgli

+0

@frglps sei genio. Grazie per la risposta ... –

+0

sì, anche il 2017 è molto utile! Grazie :) – LecheDeCrema

9

Questa è anche una soluzione (per i browser ecc.):

$string = 'hello! heeeeeeeeeeeeeeeeeeeeeereisaverylongword'; 
echo preg_replace('/([^\s]{20})(?=[^\s])/', '$1'.'<wbr>', $string); 

Si mette un <wbr> a parole con 20 o più caratteri

<wbr> significa "un'opportunità di interruzione di parola" in modo che solo rompe se deve (dettato dalla larghezza dell'elemento/browser/viewer/altro). Altrimenti è invisibile.

Buono per layout fluido/reattivo dove non c'è larghezza fissa. E non è strano come il wordwrap di php