web-dev-qa-db-fra.com

Obtenez les 100 premiers caractères d'une chaîne en respectant les mots entiers

J'ai déjà posé une question similaire auparavant, mais il me faut savoir si ce petit Tweak est possible. Je veux raccourcir une chaîne à 100 caractères et utiliser $small = substr($big, 0, 100); pour le faire. Cependant, cela prend juste les 100 premiers caractères et ne se soucie pas de savoir si cela casse un mot ou non.

Existe-t-il un moyen de reprendre les 100 premiers caractères d'une chaîne mais de ne pas casser un mot?

Exemple:

$big = "This is a sentence that has more than 100 characters in it, and I want to return a string of only full words that is no more than 100 characters!"

$small = some_function($big);

echo $small;

// OUTPUT: "This is a sentence that has more than 100 characters in it, and I want to return a string of only"

Y a-t-il un moyen de faire cela en utilisant PHP?

63
JoshFinnie

Tout ce que vous avez à faire est d'utiliser:

$pos=strpos($content, ' ', 200);
substr($content,0,$pos ); 
121
amir

Oui il y a. C’est une fonction que j’ai empruntée à un utilisateur d’autres forums il y a quelques années. Je ne peux donc pas en prendre le crédit.

//truncate a string only at a whitespace (by nogdog)
function truncate($text, $length) {
   $length = abs((int)$length);
   if(strlen($text) > $length) {
      $text = preg_replace("/^(.{1,$length})(\s.*|$)/s", '\\1...', $text);
   }
   return($text);
}

Notez qu'il ajoute automatiquement des points de suspension, si vous ne voulez pas que vous utilisiez simplement '\\1' comme deuxième paramètre de l'appel preg_replace.

35
tj111

Si vous définissez des mots comme "séquences de caractères délimités par un espace" ... Utilisez strrpos() pour rechercher le dernier espace de la chaîne, raccourcissez-le à cette position et coupez le résultat.

20
Tomalak

Sûr. Le plus simple est probablement d'écrire un wrapper autour de preg_match:

function limitString($string, $limit = 100) {
    // Return early if the string is already shorter than the limit
    if(strlen($string) < $limit) {return $string;}

    $regex = "/(.{1,$limit})\b/";
    preg_match($regex, $string, $matches);
    return $matches[1];
}

EDIT: Mis à jour pour ne pas toujours inclure un espace comme dernier caractère de la chaîne

13
PatrikAkerstrand

Cette fonction raccourcit une chaîne en ajoutant "..." à une limite de Word chaque fois que possible. La chaîne renvoyée aura une longueur maximale de $len, y compris "...".

function truncate($str, $len) {
  $tail = max(0, $len-10);
  $trunk = substr($str, 0, $tail);
  $trunk .= strrev(preg_replace('~^..+?[\s,:]\b|^...~', '...', strrev(substr($str, $tail, $len-$tail))));
  return $trunk;
}

Exemples de sorties:

  • truncate("Thanks for contributing an answer to Stack Overflow!", 15)
    renvoie "Thanks for..."
  • truncate("To learn more, see our tips on writing great answers.", 15)
    renvoie "To learn more..." (virgule également tronquée)
  • truncate("Pseudopseudohypoparathyroidism", 15)
    renvoie "Pseudopseudo..."
10
daluege

C'est mon approche, basée sur la réponse d'amir, mais elle ne laisse aucun mot rendre la chaîne plus longue que la limite, en utilisant strrpos () avec un décalage négatif.

Simple mais fonctionne. J'utilise la même syntaxe que dans la fonction d'assistance str_limit () de Laravel, au cas où vous souhaiteriez l'utiliser sur un projet autre que Laravel.

function str_limit($value, $limit = 100, $end = '...')
{
    $limit = $limit - mb_strlen($end); // Take into account $end string into the limit
    $valuelen = mb_strlen($value);
    return $limit < $valuelen ? mb_substr($value, 0, mb_strrpos($value, ' ', $limit - $valuelen)) . $end : $value;
}
8
OMA

Voici une excellente solution avec des dots à la fin avec des mots entiers

function text_cut($text, $length = 200, $dots = true) {
    $text = trim(preg_replace('#[\s\n\r\t]{2,}#', ' ', $text));
    $text_temp = $text;
    while (substr($text, $length, 1) != " ") { $length++; if ($length > strlen($text)) { break; } }
    $text = substr($text, 0, $length);
    return $text . ( ( $dots == true && $text != '' && strlen($text_temp) > $length ) ? '...' : ''); 
}

Entrée: Lorem ipsum dolor sit amet, consectetur elit adipisicing, luimment une personne temporairement incarnée, et dolore magna aliqua. Tout en un minimum de poids, l’exercice de nos exercices en cours de travail, mais il n’existe que d’excellents résultats. Duis aute irure dolor in reprrehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Résultat: Lorem ipsum dolor sit amet, consectetur elit adipisicing, luimment une personne temporairement incarnée, et dolore magna aliqua. Utilisez-le pour minimiser votre consommation, votre activité physique doit être traitée ...

4

Cela fonctionne bien pour moi, je l'utilise dans mon script

<?PHP
$big = "This is a sentence that has more than 100 characters in it, and I want to return a string of only full words that is no more than 100 characters!";
$small = some_function($big);
echo $small;

function some_function($string){
     $string = substr($string,0,100);
     $string = substr($string,0,strrpos($string," "));
     return $string;
}
?>

bonne chance

4
ahmed

Le problème avec la réponse acceptée est que la chaîne de résultat dépasse la limite, c’est-à-dire qu’elle peut dépasser 100 caractères puisque strpos regardera après le décalage et que votre longueur dépassera toujours votre limite. Si le dernier mot est long, comme squirreled, la longueur de votre résultat sera 111 (pour vous donner une idée).

Une meilleure solution consiste à utiliser la fonction wordwrap:

function truncate($str, $length = 125, $append = '...') {
    if (strlen($str) > $length) {
        $delim = "~\n~";
        $str = substr($str, 0, strpos(wordwrap($str, $length, $delim), $delim)) . $append;
    } 

    return $str;
}


echo truncate("The quick brown fox jumped over the lazy dog.", 5);

De cette façon, vous pouvez être sûr que la chaîne est tronquée sous votre limite (et ne dépasse jamais)

P.S. Ceci est particulièrement utile si vous envisagez de stocker la chaîne tronquée dans votre base de données avec une colonne avec-fixe avec comme VARCHAR (50), etc. 

P.P.S. Notez le délimiteur spécial dans le wordwrap. Cela permet de s’assurer que votre chaîne est tronquée correctement, même si elle contient des nouvelles lignes (sinon, elle tronquera la première ligne que vous ne voulez pas).

3
supersan

Cela l'a fait pour moi ...

//trim message to 100 characters, regardless of where it cuts off
$msgTrimmed = mb_substr($var,0,100);

//find the index of the last space in the trimmed message
$lastSpace = strrpos($msgTrimmed, ' ', 0);

//now trim the message at the last space so we don't cut it off in the middle of a Word
echo mb_substr($msgTrimmed,0,$lastSpace)
2
katfish

Voici ma solution:

/**
 * get_words_until() Returns a string of delimited text parts up to a certain length
 * If the "words" are too long to limit, it just slices em up to the limit with an Ellipsis "..."
 *
 * @param $paragraph - The text you want to Parse
 * @param $limit - The maximum character length, e.g. 160 chars for SMS
 * @param string $delimiter - Use ' ' for words and '. ' for sentences (abbreviation bug) :)
 * @param null $Ellipsis - Use '...' or ' (more)' - Still respects character limit
 *
 * @return string
 */
function get_words_until($paragraph, $limit, $delimiter = ' ', $Ellipsis = null)
{
    $parts = explode($delimiter, $paragraph);

    $preview = "";

    if ($Ellipsis) {
        $limit = $limit - strlen($Ellipsis);
    }

    foreach ($parts as $part) {
        $to_add = $part . $delimiter;
        if (strlen($preview . trim($to_add)) <= $limit) { // Can the part fit?
            $preview .= $to_add;
            continue;
        }
        if (!strlen($preview)) { // Is preview blank?
            $preview = substr($part, 0, $limit - 3) . '...'; // Forced Ellipsis
            break;
        }
    }

    return trim($preview) . $Ellipsis;
}

Dans votre cas ce serait (exemple):

$big = "This is a sentence that has more than 100 characters in it, and I want to return a string of only full words that is no more than 100 characters!"

$small = get_words_until($big, 100);
2
Kevin K
function truncate ($str, $length) {
    if (strlen($str) > $length) {
        $str = substr($str, 0, $length+1);
        $pos = strrpos($str, ' ');
        $str = substr($str, 0, ($pos > 0)? $pos : $length);
    }
    return $str;
}

Exemple:

print truncate('The first step to eternal life is you have to die.', 25);

string (25) "Le premier pas vers l'éternel"

print truncate('The first step to eternal life is you have to die.', 12);

string (9) "Le premier"

print truncate('FirstStepToEternalLife', 5);

string (5) "Premier"

2
Aigars Matulis

Je m'excuse d'avoir ressuscité cette question, mais je suis tombé sur ce fil et ai trouvé un petit problème. Pour les personnes voulant une limite de caractères qui supprime les mots qui dépasseraient votre limite donnée, les réponses ci-dessus fonctionnent très bien. Dans mon cas spécifique, j'aime afficher un mot si la limite tombe au milieu dudit mot. J'ai décidé de partager ma solution au cas où quelqu'un d'autre recherche cette fonctionnalité et doit inclure des mots au lieu de les supprimer.

function str_limit($str, $len = 100, $end = '...')
{
    if(strlen($str) < $len)
    {
        return $str;
    }

    $str = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));

    if(strlen($str) <= $len)
    {
        return $str;
    }

    $out = '';
    foreach(explode(' ', trim($str)) as $val)
    {
        $out .= $val . ' ';

        if(strlen($out) >= $len)
        {
            $out = trim($out);
            return (strlen($out) == strlen($str)) ? $out : $out . $end;
        }
    }
}

Exemples:

  • Entrée: echo str_limit('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', 100, '...');
  • Sortie: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore...
  • Entrée: echo str_limit('Lorem ipsum', 100, '...');
  • Sortie: Lorem ipsum
  • Entrée: echo str_limit('Lorem ipsum', 1, '...');
  • Sortie: Lorem...
1
beaudierman

Voici une autre façon de faire cela.

$big = "This is a sentence that has more than 100 characters in it, and I want to return a string of only full words that is no more than 100 characters!"
$big = trim( $big );
$small = $big;
                if( strlen( $big ) > 100 ){
                $small = mb_substr( $small, 0, 100 );
                $last_position = mb_strripos( $small, ' ' );
                    if( $last_position > 0 ){
                    $small = mb_substr( $small, 0, $last_position );
                    }
                }

            echo $small; 

OR

 echo ( strlen( $small ) <  strlen( $big ) ? $small.'...' : $small );

C'est aussi un coffre-fort multi-octets et fonctionne également même s'il n'y a pas d'espaces, auquel cas il retournera simplement les 100 premiers caractères. Il prend les 100 premiers caractères, puis cherche de la fin au délimiteur Word le plus proche.

1
Alex

Une autre façon plus simple que je fais.

function limit_words($string, $Word_limit = 10)
{
    $words = explode(" ", $string);
    if (count($words) > $Word_limit) {
        return implode(" ", array_splice($words, 0, $Word_limit)) . ' ...';
    }
    return implode(" ", array_splice($words, 0, $Word_limit));
}
1
zarpio

Encore une réponse! Je n'étais pas complètement satisfait des autres réponses, et je voulais une «coupure dure» (si possible, Word break avant $ max_characters), alors voici ma fonction de contribuer!

/**
 * Shortens a string (if necessary), trying for a non-Word character before character limit, adds an Ellipsis and
 * returns. Falls back to a forced cut if no non-Word characters exist before.
 *
 * @param string $content
 * @param int    $max_characters - number of characters to start looking for a space / break.
 * @param bool   $add_Ellipsis   - add Ellipsis if content is shortened
 *
 * @return string
 */
public static function shorten( $content, $max_characters = 100, $add_Ellipsis = TRUE ) {
    if ( strlen( $content ) <= $max_characters ) {
        return $content;
    }

    // search for non-Word characters
    $match_count = preg_match_all( '/\W/', $content, $matches, PREG_OFFSET_CAPTURE );

    // force a hard break if can't find another good solution
    $pos = $max_characters;

    if ( $match_count > 0 ) {
        foreach ( $matches[0] as $match ) {
            // check if new position fits within
            if ( $match[1] <= $max_characters ) {
                $pos = $match[1];
            } else {
                break;
            }
        }
    }

    $suffix = ( $add_Ellipsis ) ? '&hellip;' : '';

    return substr( $content, 0, $pos ) . $suffix;
}
0
ryanm

wordwrap formate la chaîne en fonction de la limite, les sépare avec\n Nous avons donc des lignes plus petites que 50. Les commandes ne sont pas séparées. nous avons donc un tableau correspondant aux lignes list rassemble le premier élément.

liste ($ short) = exploser ("\ n", wordwrap ($ ALi, 50));

s'il vous plaît rep Evert , puisque je ne peux pas commenter ou rep.

voici un exemple de parcours

php >  $ALi = "ALi veli krbin yz doksan esikesiksld sjkas laksjald lksjd asldkjadlkajsdlakjlksjdlkaj aslkdj alkdjs akdljsalkdj ";
php > list($short) = explode("\n",wordwrap($ALi ,50));
php > var_dump($short);
string(42) "ALi veli krbin yz doksan esikesiksld sjkas"
php > $ALi ='';
php > list($short) = explode("\n",wordwrap($ALi ,50));
php > var_dump($short);
string(0) ""
0
nerkn

## Obtenir le premier caractère limité d'une chaîne ## 

<?php 
  $content= $row->title;
  $result = substr($content, 0, 70);
  echo $result; 
  ?>
0
sooraj subramanyan