Pregunta

Estoy tratando de llegar a la siguiente función que trunca la cadena de palabras enteras (si es posible, de lo contrario, debe truncar caracteres):

function Text_Truncate($string, $limit, $more = '...')
{
    $string = trim(html_entity_decode($string, ENT_QUOTES, 'UTF-8'));

    if (strlen(utf8_decode($string)) > $limit)
    {
        $string = preg_replace('~^(.{1,' . intval($limit) . '})(?:\s.*|$)~su', '$1', $string);

        if (strlen(utf8_decode($string)) > $limit)
        {
            $string = preg_replace('~^(.{' . intval($limit) . '}).*~su', '$1', $string);
        }

        $string .= $more;
    }

    return trim(htmlentities($string, ENT_QUOTES, 'UTF-8', true));
}

Aquí hay algunas pruebas:

// Iñtërnâtiônàlizætiøn and then the quick brown fox... (49 + 3 chars)
echo dyd_Text_Truncate('Iñtërnâtiônàlizætiøn and then the quick brown fox jumped overly the lazy dog and one day the lazy dog humped the poor fox down until she died.', 50, '...');

// Iñtërnâtiônàlizætiøn_and_then_the_quick_brown_fox_...  (50 + 3 chars)
echo dyd_Text_Truncate('Iñtërnâtiônàlizætiøn_and_then_the_quick_brown_fox_jumped_overly_the_lazy_dog and one day the lazy dog humped the poor fox down until she died.', 50, '...');

Ambos trabajan como es, sin embargo, si me cae el segundo preg_replace() consigo el siguiente:

  

Iñtërnâtiônàlizætiøn_and_then_the_quick_brown_fox_jumped_overly_the_lazy_dog   y un día el perro perezoso joroba del   pobre zorro abajo hasta que murió ....

No se puede utilizar substr() ya que sólo funciona en nivel de byte y no tienen acceso a mb_substr() ATM, he hecho varios intentos para unirse a la segunda expresión regular con el primero, pero sin éxito.

Por favor, ayuda S.M.S., he estado luchando con esto durante casi una hora.


EDIT: Lo siento, he estado despierto durante 40 horas y sin vergüenza echado de menos esto:

$string = preg_replace('~^(.{1,' . intval($limit) . '})(?:\s.*|$)?~su', '$1', $string);

Sin embargo, si alguien tiene una expresión regular más optimizada (o uno que ignora el espacio final) Por favor comparta:

"Iñtërnâtiônàlizætiøn and then "
"Iñtërnâtiônàlizætiøn_and_then_"

EDIT 2:? Todavía no puedo deshacerme del espacio en blanco final, alguien me puede ayuda a cabo

Datos 3: De acuerdo, ninguno de mis ediciones hizo realmente el trabajo, que estaba siendo engañado por RegexBuddy - probablemente debería dejar esta tarea a otro día y dormir un poco. Off para hoy.

¿Fue útil?

Solución

Tal vez le puede dar una mañana feliz después de una larga noche de pesadillas RegExp:

'~^(.{1,' . intval($limit) . '}(?<=\S)(?=\s)|.{'.intval($limit).'}).*~su'

ebullición abajo:

^      # Start of String
(       # begin capture group 1
 .{1,x} # match 1 - x characters
 (?<=\S)# lookbehind, match must end with non-whitespace 
 (?=\s) # lookahead, if the next char is whitespace, match
 |      # otherwise test this:
 .{x}   # got to x chars anyway.
)       # end cap group
.*     # match the rest of the string (since you were using replace)

Siempre se puede añadir el |$ hasta el final de (?=\s) pero desde su código ya estaba comprobando que la longitud de la cadena era más larga que la $limit, no sentí ese caso sería NECESARIO.

Otros consejos

Ha considerado el uso de ajuste de línea? ( http://us3.php.net/wordwrap )

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top