variable una str_replace recorrer parte extraer eliminar caracteres caracter cadena buscar php string function

una - trim php



Cómo truncar una cadena en PHP a la palabra más cercana a una cierta cantidad de caracteres? (25)

Tengo un fragmento de código escrito en PHP que extrae un bloque de texto de una base de datos y lo envía a un widget en una página web. El bloque de texto original puede ser un artículo extenso o una oración corta o dos; pero para este widget no puedo mostrar más de, digamos, 200 caracteres. Podría usar substr () para cortar el texto a 200 caracteres, pero el resultado sería cortar en el medio de las palabras. Lo que realmente quiero es cortar el texto al final de la última palabra antes de 200 caracteres.


Al usar la función wordwrap . Divide los textos en varias líneas de manera que el ancho máximo es el que especificó, rompiendo los límites de las palabras. Después de dividir, simplemente toma la primera línea:

substr($string, 0, strpos(wordwrap($string, $your_desired_width), "/n"));

Una cosa que este oneliner no maneja es el caso cuando el texto en sí es más corto que el ancho deseado. Para manejar este caso extremo, uno debería hacer algo como:

if (strlen($string) > $your_desired_width) { $string = wordwrap($string, $your_desired_width); $string = substr($string, 0, strpos($string, "/n")); }

La solución anterior tiene el problema de cortar prematuramente el texto si contiene una nueva línea antes del punto de corte real. Aquí una versión que resuelve este problema:

function tokenTruncate($string, $your_desired_width) { $parts = preg_split(''/([/s/n/r]+)/'', $string, null, PREG_SPLIT_DELIM_CAPTURE); $parts_count = count($parts); $length = 0; $last_part = 0; for (; $last_part < $parts_count; ++$last_part) { $length += strlen($parts[$last_part]); if ($length > $your_desired_width) { break; } } return implode(array_slice($parts, 0, $last_part)); }

Además, aquí está la clase de prueba PHPUnit utilizada para probar la implementación:

class TokenTruncateTest extends PHPUnit_Framework_TestCase { public function testBasic() { $this->assertEquals("1 3 5 7 9 ", tokenTruncate("1 3 5 7 9 11 14", 10)); } public function testEmptyString() { $this->assertEquals("", tokenTruncate("", 10)); } public function testShortString() { $this->assertEquals("1 3", tokenTruncate("1 3", 10)); } public function testStringTooLong() { $this->assertEquals("", tokenTruncate("toooooooooooolooooong", 10)); } public function testContainingNewline() { $this->assertEquals("1 3/n5 7 9 ", tokenTruncate("1 3/n5 7 9 11 14", 10)); } }

EDITAR:

Los caracteres especiales UTF8 como ''à'' no se manejan. Agregue ''u'' al final de REGEX para manejarlo:

$parts = preg_split(''/([/s/n/r]+)/u'', $string, null, PREG_SPLIT_DELIM_CAPTURE);


Aquí está mi función basada en el enfoque de @ Cd-MaN.

function shorten($string, $width) { if(strlen($string) > $width) { $string = wordwrap($string, $width); $string = substr($string, 0, strpos($string, "/n")); } return $string; }


Aquí puedes probar esto

substr( $str, 0, strpos($str, '' '', 200) );


Aqui tienes:

function neat_trim($str, $n, $delim=''…'') { $len = strlen($str); if ($len > $n) { preg_match(''/(.{'' . $n . ''}.*?)/b/'', $str, $matches); return rtrim($matches[1]) . $delim; } else { return $str; } }


Así es como lo hice:

$string = "I appreciate your service & idea to provide the branded toys at a fair rent price. This is really a wonderful to watch the kid not just playing with variety of toys but learning faster compare to the other kids who are not using the BooksandBeyond service. We wish you all the best"; print_r(substr($string, 0, strpos(wordwrap($string, 250), "/n")));


Basado en la expresión regular de @Justin Poliey:

// Trim very long text to 120 characters. Add an ellipsis if the text is trimmed. if(strlen($very_long_text) > 120) { $matches = array(); preg_match("/^(.{1,120})[/s]/i", $very_long_text, $matches); $trimmed_text = $matches[0]. ''...''; }


Creo que esta es la forma más fácil de hacerlo:

$lines = explode(''♦♣♠'',wordwrap($string, $length, ''♦♣♠'')); $newstring = $lines[0] . '' &bull; &bull; &bull;'';

Estoy usando los caracteres especiales para dividir el texto y cortarlo.


Creo una función más similar a substr, y usando la idea de @Dave.

function substr_full_word($str, $start, $end){ $pos_ini = ($start == 0) ? $start : stripos(substr($str, $start, $end), '' '') + $start; if(strlen($str) > $end){ $pos_end = strrpos(substr($str, 0, ($end + 1)), '' ''); } // IF STRING SIZE IS LESSER THAN END if(empty($pos_end)){ $pos_end = $end; } // FALLBACK return substr($str, $pos_ini, $pos_end); }

Ps .: El corte de longitud total puede ser menor que el substr.


Encuentro que esto funciona:

function abbreviate_string_to_whole_word ($ string, $ max_length, $ buffer) {

if (strlen($string)>$max_length) { $string_cropped=substr($string,0,$max_length-$buffer); $last_space=strrpos($string_cropped, " "); if ($last_space>0) { $string_cropped=substr($string_cropped,0,$last_space); } $abbreviated_string=$string_cropped."&nbsp;..."; } else { $abbreviated_string=$string; } return $abbreviated_string;

}

El buffer le permite ajustar la longitud de la cadena devuelta.


Es sorprendente lo difícil que es encontrar la solución perfecta a este problema. Todavía no he encontrado una respuesta en esta página que no falle al menos en algunas situaciones (especialmente si la cadena contiene nuevas líneas o pestañas, o si el salto de palabra es cualquier cosa que no sea un espacio, o si la cadena tiene UTF- 8 caracteres multibyte).

Aquí hay una solución simple que funciona en todos los casos. Hubo respuestas similares aquí, pero el modificador "s" es importante si quieres que funcione con una entrada de varias líneas, y el modificador "u" hace que evalúe correctamente los caracteres UTF-8 multibyte.

function wholeWordTruncate($s, $characterCount) { if (preg_match("/^.{1,$characterCount}/b/su", $s, $match)) return $match[0]; return $s; }

Un posible caso de borde con esto ... si la cadena no tiene ningún espacio en absoluto en los primeros caracteres $ characterCount, devolverá la cadena completa. Si lo prefiere, fuerza un corte en $ characterCount incluso si no es un límite de palabra, puede usar esto:

function wholeWordTruncate($s, $characterCount) { if (preg_match("/^.{1,$characterCount}/b/su", $s, $match)) return $match[0]; return mb_substr($return, 0, $characterCount); }

Una última opción, si desea que agregue puntos suspensivos si trunca la cadena ...

function wholeWordTruncate($s, $characterCount, $addEllipsis = '' …'') { $return = $s; if (preg_match("/^.{1,$characterCount}/b/su", $s, $match)) $return = $match[0]; else $return = mb_substr($return, 0, $characterCount); if (strlen($s) > strlen($return)) $return .= $addEllipsis; return $return; }


Esta es una pequeña solución para la respuesta de Mattmac:

preg_replace(''//s+?(/S+)?$/'', '''', substr($string . '' '', 0, 201));

La única diferencia es agregar un espacio al final de $ string. Esto garantiza que la última palabra no se corte según el comentario de ReX357.

No tengo suficientes puntos de repetición para agregar esto como comentario.


Esto devolverá los primeros 200 caracteres de palabras:

preg_replace(''//s+?(/S+)?$/'', '''', substr($string, 0, 201));


La siguiente solución nació cuando noté un parámetro $ break de la función wordwrap :

string wordwrap (cadena $ str [, int $ ancho = 75 [, cadena $ break = "/ n" [, bool $ corte = falso]]])

Aquí está la solución :

/** * Truncates the given string at the specified length. * * @param string $str The input string. * @param int $width The number of chars at which the string will be truncated. * @return string */ function truncate($str, $width) { return strtok(wordwrap($str, $width, ".../n"), "/n"); }

Ejemplo 1.

print truncate("This is very long string with many chars.", 25);

El ejemplo anterior dará como resultado:

This is very long string...

Ejemplo n. ° 2

print truncate("This is short string.", 25);

El ejemplo anterior dará como resultado:

This is short string.


Lo usé antes

<?php $your_desired_width = 200; $string = $var->content; if (strlen($string) > $your_desired_width) { $string = wordwrap($string, $your_desired_width); $string = substr($string, 0, strpos($string, "/n")) . " More..."; } echo $string; ?>


Ok, tengo otra versión de esto basada en las respuestas anteriores, pero tomando más cosas en cuenta (utf-8, / n y & nbsp;), también una línea que elimina los códigos abreviados de wordpress comentados si se usa con wp.

function neatest_trim($content, $chars) if (strlen($content) > $chars) { $content = str_replace(''&nbsp;'', '' '', $content); $content = str_replace("/n", '''', $content); // use with wordpress //$content = strip_tags(strip_shortcodes(trim($content))); $content = strip_tags(trim($content)); $content = preg_replace(''//s+?(/S+)?$/'', '''', mb_substr($content, 0, $chars)); $content = trim($content) . ''...''; return $content; }


Puede ser que esto ayude a alguien:

<?php $string = "Your line of text"; $spl = preg_match("/([, /./d/-''''/"/"_()]*/w+[, /./d/-''''/"/"_()]*){50}/", $string, $matches); if (isset($matches[0])) { $matches[0] .= "..."; echo "<br />" . $matches[0]; } else { echo "<br />" . $string; } ?>


Sé que esto es viejo, pero ...

function _truncate($str, $limit) { if(strlen($str) < $limit) return $str; $uid = uniqid(); return array_shift(explode($uid, wordwrap($str, $limit, $uid))); }


Se agregaron instrucciones IF / ELSEIF al código de Dave y AmalMurali para manejar cadenas sin espacios

if ((strpos($string, '' '') !== false) && (strlen($string) > 200)) { $WidgetText = substr($string, 0, strrpos(substr($string, 0, 200), '' '')); } elseif (strlen($string) > 200) { $WidgetText = substr($string, 0, 200); }


Tenga en cuenta que cada vez que se divida por "palabra" en cualquier lugar, algunos idiomas, como el chino y el japonés, no usan un carácter de espacio para dividir palabras. Además, un usuario malintencionado podría simplemente ingresar texto sin espacios, o usar un aspecto Unicode similar al carácter de espacio estándar, en cuyo caso cualquier solución que use puede terminar mostrando todo el texto de todos modos. Una forma de evitar esto puede ser comprobar la longitud de la cadena después de dividirla en espacios de forma normal, y luego, si la cadena sigue estando por encima de un límite anormal, tal vez 225 caracteres en este caso, seguir adelante y dividirlo tontamente en ese límite.

Una advertencia más con cosas como esta cuando se trata de caracteres que no son ASCII; las cadenas que las contienen pueden ser interpretadas por el estándar strlen () de PHP como más largas de lo que realmente son, porque un solo carácter puede tomar dos o más bytes en lugar de uno solo. Si solo usa las funciones strlen () / substr () para dividir cadenas, ¡puede dividir una cadena en el medio de un personaje! En caso de duda, mb_strlen() / mb_substr() son un poco más infalibles.


Tengo una función que hace casi lo que quieres, si vas a hacer algunas ediciones, se ajustará exactamente:

<?php function stripByWords($string,$length,$delimiter = ''<br>'') { $words_array = explode(" ",$string); $strlen = 0; $return = ''''; foreach($words_array as $word) { $strlen += mb_strlen($word,''utf8''); $return .= $word." "; if($strlen >= $length) { $strlen = 0; $return .= $delimiter; } } return $return; } ?>


Usaría la función preg_match para hacer esto, ya que lo que quieres es una expresión bastante simple.

$matches = array(); $result = preg_match("/^(.{1,199})[/s]/i", $text, $matches);

La expresión significa "hacer coincidir cualquier subcadena que comience desde el comienzo de la longitud 1-200 que termina con un espacio". El resultado es en $ resultado, y el partido está en $ matches. Eso se ocupa de su pregunta original, que termina específicamente en cualquier espacio. Si desea que termine en nuevas líneas, cambie la expresión regular a:

$result = preg_match("/^(.{1,199})[/n]/i", $text, $matches);


Utilice strpos y substr:

<?php $longString = "I have a code snippet written in PHP that pulls a block of text."; $truncated = substr($longString,0,strpos($longString,'' '',30)); echo $truncated;

Esto le dará una cadena truncada en el primer espacio después de 30 caracteres.


$WidgetText = substr($string, 0, strrpos(substr($string, 0, 200), '' ''));

Y ahí lo tiene: un método confiable de truncar cualquier cuerda a la palabra completa más cercana, mientras se mantiene por debajo de la longitud máxima de la cuerda.

He intentado los otros ejemplos anteriores y no produjeron los resultados deseados.


$shorttext = preg_replace(''/^([/s/S]{1,200})[/s]+?[/s/S]+/'', ''$1'', $fulltext);

Descripción:

  • ^ - comienza desde el comienzo de la cadena
  • ([/s/S]{1,200}) - obtiene de 1 a 200 de cualquier personaje
  • [/s]+? - No incluya espacios al final del texto corto para que podamos evitar la word ... lugar de la word...
  • [/s/S]+ - coincide con el resto del contenido

Pruebas:

  1. regex101.com agreguemos or algunos otros r
  2. regex101.com orrrr exactamente 200 caracteres.
  3. regex101.com después de excluido el quinto orrrrr .

Disfrutar.


/* Cut the string without breaking any words, UTF-8 aware * param string $str The text string to split * param integer $start The start position, defaults to 0 * param integer $words The number of words to extract, defaults to 15 */ function wordCutString($str, $start = 0, $words = 15 ) { $arr = preg_split("/[/s]+/", $str, $words+1); $arr = array_slice($arr, $start, $words); return join('' '', $arr); }

Uso:

$input = ''Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna liqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.''; echo wordCutString($input, 0, 10);

Esto generará las primeras 10 palabras.

La función preg_split se usa para dividir una cadena en subcadenas. Los límites a lo largo de los cuales se debe dividir la cadena se especifican utilizando un patrón de expresiones regulares.

preg_split función preg_split toma 4 parámetros, pero solo los primeros 3 son relevantes para nosotros en este momento.

Primer parámetro - Patrón El primer parámetro es el patrón de expresiones regulares a lo largo del cual se dividirá la cadena. En nuestro caso, queremos dividir la cadena entre los límites de las palabras. Por lo tanto, utilizamos una clase de caracteres predefinida /s que coincide con los caracteres de espacios en blanco, como espacio, tabulación, retorno de carro y avance de línea.

Segundo parámetro - Cadena de entrada El segundo parámetro es la cadena de texto largo que queremos dividir.

Tercer parámetro - Límite El tercer parámetro especifica el número de subcadenas que se deben devolver. Si establece el límite en n , preg_split devolverá una matriz de n elementos. Los primeros n-1 elementos contendrán las subcadenas. El último (n th) elemento contendrá el resto de la cadena.