2012-03-22 25 views
14

Estoy buscando una manera de hacer que la envoltura de palabras en PHP sea un poco más inteligente. Por lo tanto, no interrumpe las palabras largas dejando palabras pequeñas anteriores solo en una línea.Concordancia de palabras más inteligente en PHP para palabras largas?

Digamos que tengo este (el texto real siempre es completamente dinámico, esto es sólo para mostrar):

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

Este salidas:

hola!
heeeeeeeeeeeeeeereisavery
longword

Sede, que sale de la pequeña palabra por sí sola en la primera línea. ¿Cómo puedo conseguir que supere algo más como esto:

hello! heeeeeeeeeeee
eeereisaverylongword

Por lo tanto, utiliza cualquier espacio disponible en cada línea. He intentado varias funciones personalizadas, pero ninguna ha sido efectiva (o tenían algunos inconvenientes).

+0

Acabo de llegar desde Google. Me sorprende que esto no funcione. ¿Es esto un error con la función incorporada de PHP? Me parece que cuando establece el último argumento como verdadero, debe usar todo el espacio disponible. ¿Por qué no haría eso? –

+0

@Andrew Sí, no lo sé. Puede usar el método de envoltura de CSS, o este http://stackoverflow.com/questions/9815040/smarter-word-wrap-in-php-for-long-words/25273135#25273135 (si es para webbrowsing, etc.). Paz – mowgli

Respuesta

15

He tenido una ir a la función personalizada para este ajuste de línea inteligente:

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"; 

EDITAR: vio a un par de advertencias. Una advertencia importante con esto (y también con la función nativa) es la falta de soporte multibyte.

+0

¿Qué establece $ width = 75 establecido excactly? – mowgli

+0

La firma de función es exactamente la de wordwrap (sin el parámetro break), por lo que establece un ancho de envoltura predeterminado de 75 caracteres. – cmbuckley

+0

nada, solo son los valores predeterminados que está usando. En caso de que no proporcione el suyo propio de '11', entonces se usará' 75'. – Eli

2

Esto debería hacer el truco ...

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

Acabo de usar algunas palabras de ejemplo. En uso real, el texto sería completamente dinámico, así que no podría usar ese – mowgli

+0

No estoy seguro exactamente de cómo intentas hacer esto, pero ¿por qué no podrías cambiar esto dinámicamente? Solo use variables para configurar su texto –

+0

¿Cambia dinámicamente qué? El texto puede ser cualquier cosa, cualquier longitud, cualquier cantidad de palabras. No sé cuál será la primera palabra o cualquier palabra;) – mowgli

5

Puede utilizar CSS para lograr esto.

word-wrap: break-word; 

Eso romperá la palabra para usted. Aquí hay un enlace para verlo en acción:

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

+3

No estoy rompiendo las palabras de un navegador – mowgli

+0

esto no funcionó para mí. Lo probé en la td de una mesa. Apliqué algunos 'width' en estilo y' word-wrap: break-word; ' –

+0

Es 2014 y aún no funciona en todos los navegadores. A veces php cubre tu trasero. – Maelish

11

¿Qué tal

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

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

que da salida a

hello! heeeeeeeeeeeeeeere                                       
isaverylongword 

str_split() convierte la cadena en una matriz de $ romper tamaño trozos.

implosión() se une a la matriz de nuevo juntos como una cadena usando el pegamento que en este caso es un marcador de fin de línea (PHP_EOL) aunque podría fácilmente ser una '<br/>'

+0

¿A dónde va la palabra envoltura? ;) – mowgli

+0

@frglps eres genio. Gracias por su respuesta ... –

+0

¡incluso ahora es 2017, esto es muy útil! Gracias :) – LecheDeCrema

9

Esta es también una solución (para navegadores, etc.):

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

Pone una <wbr> ante las palabras con 20 o más caracteres

<wbr> significa "oportunidad de salto de palabra" por lo que única se rompe si se tiene que (dictado por el ancho del elemento/navegador/espectador/otro). Es invisible de lo contrario.

Bueno para el diseño fluido/sensible donde no hay ancho fijo. Y no se ve raro como la frase de php

Cuestiones relacionadas