Comment Tronquer une chaîne de caractères en PHP pour le terme le plus proche pour un certain nombre de caractères?
J'ai un extrait de code écrit en PHP qui tire un bloc de texte à partir d'une base de données et les envoie à un widget sur une page web. L'original de bloc de texte peut être un long article ou une courte phrase ou deux, mais pour ce widget je ne peux pas afficher plus de, disons, 200 caractères. Je pourrais utiliser substr() pour couper le texte à 200 caractères, mais le résultat serait de couper dans le milieu des mots, ce que je veux est de hacher le texte à la fin de la dernière mot avant de 200 caractères.
- La question à l'intention de dire que le texte tronqué, sera adapté en un nombre fixe de pixels sur une page web. Dans ce cas, en fonction de police, l'espace requis par char n'est pas constante. Et donc nous ne pouvons pas supposer que 200 caractères vont s'intégrer au mieux dans pixels disponibles. Jusqu'à présent (jusqu'02-Mar-2011), tous ci-dessous les réponses sont manquantes ce point et donc aucun d'entre eux offrent une solution fiable. -:(
- Non, pas vraiment. Vous pouvez définir la police dans un moyen fiable, et ensuite mesurer le scénario du pire cas aka combien de large personnages serait de les intégrer. Et si vous avez besoin d'être à 100% sûr de savoir comment navigateur rendu, ce n'est pas un problème PHP plus de toute façon.
- Essayez Ce Lien, Peut Vous aider stackoverflow.com/a/26098951/3944217
- Vous pouvez trouver
s($str)->truncateSafely(200)
utile, que l'on trouve dans cette bibliothèque autonome.
Vous devez vous connecter pour publier un commentaire.
À l'aide de la wordwrap fonction. Il scinde les textes en lignes multiples, tels que la largeur maximale est celui que vous avez spécifié, la rupture aux limites des mots. Après la séparation, il vous suffit de prendre la première ligne:
Une chose de cette oneliner ne gère pas le cas où le texte lui-même est plus courte que la largeur désirée. Pour gérer ce bord-cas, on doit faire quelque chose comme:
La solution ci-dessus a le problème de l'prématurément de la coupe de la texte si elle contient un saut de ligne avant le cutpoint. Ici, une version qui permet de résoudre ce problème:
Aussi, ici, est le PHPUnit testclass utilisé pour tester la mise en œuvre:
EDIT :
Spécial des caractères UTF8 comme 'à' ne sont pas traitées. Ajouter en " u " à la fin de la REGEX pour le manipuler:
$parts = preg_split('/([\s\n\r]+)/u', $string, null, PREG_SPLIT_DELIM_CAPTURE);
\n
avant de la largeur désirée.Arabic
des lettres et de la réduction de son afin de corriger les mots maintenant, avec l'aide detokenTruncate
fonction.. tnx un million 🙂tokenTruncate()
, utilisez le caractère asciiunit seperator
qui est ce à quoi il est destiné:substr($content, 0, strpos(wordwrap($content, 350, chr(31)), chr(31)))
Revenir les 200 premiers caractères de mots:
if (strlen($string) > $your_desired_width) { preg_replace(...); }
/\s+?(?:\S+)?$/
Et là vous l'avez — un moyen fiable de les tronquer une chaîne à l'entier le plus proche parole, tout en restant sous la longueur maximale de la chaîne.
J'ai essayé d'autres exemples ci-dessus et elles n'ont pas produit les résultats escomptés.
if
déclaration:if (strlen($str) > 200) { ... }
$WidgetText = substr($string, 0, strpos($string, ' ', 200));
La solution suivante est né lorsque j'ai remarqué un $pause paramètre de wordwrap fonction:
Ici est la solution:
Exemple #1.
L'exemple ci-dessus va afficher:
Exemple #2.
L'exemple ci-dessus va afficher:
description
d'un billet de blog)preg_replace('/\s+/', ' ', $description)
à remplacer tous les espaces par un espace simple 😉Garder à l'esprit chaque fois que vous êtes fractionnement par "mot" n'importe où que certaines langues, comme le Chinois et le Japonais n'utilisez pas un caractère d'espace pour fractionner les mots. Aussi, un utilisateur malveillant pourrait simplement saisir du texte sans espaces, ou à l'aide de certains Unicode qui se ressemblent à l'espace standard, auquel cas, toute solution que vous utilisez peut finir par afficher l'intégralité du texte, de toute façon. Un moyen de contourner cela peut être de vérifier la longueur de la corde après le fractionnement sur des espaces comme d'habitude, puis, si la chaîne est encore au-dessus une anomalie de la limite peut-être à 225 caractères dans ce cas - aller de l'avant et de le diviser dumbly à cette limite.
Encore une mise en garde avec ce genre de choses quand il s'agit de caractères non-ASCII; les chaînes contenant peut être interprété par PHP standard strlen() comme étant plus qu'ils ne le sont, parce qu'un seul caractère peut prendre deux ou plus de deux octets au lieu d'un seul. Si vous venez d'utiliser la strlen()/substr() des fonctions split chaînes, vous pouvez diviser une chaîne au milieu d'un personnage! En cas de doute, mb_strlen()/mb_substr() sont un peu plus infaillible.
Utilisation strpos et substr:
Cela vous donnera une chaîne tronquée à la première place au bout de 30 caractères.
Voici ma fonction sur la base d' @Cd-Homme approche.
Ici, vous allez:
Il est surprenant de constater combien il est difficile est de trouver la solution parfaite à ce problème. Je n'ai pas encore trouvé la réponse sur cette page qui n'a pas manqué, au moins dans certaines situations (en particulier si la chaîne contient des retours à la ligne ou des tabulations, ou si le mot rupture n'est rien d'autre qu'un espace, ou si la chaîne a de l'UTF-8 caractères multioctets).
Voici une solution simple qui fonctionne dans tous les cas. Il y avait le même genre de réponses ici, mais le "s" modificateur est important si vous voulez qu'il fonctionne avec multi-ligne d'entrée, et le "u" modificateur rend évaluer correctement l'UTF-8, les caractères multioctets.
Un possible cas de bord avec ce... si la chaîne n'a pas d'espaces dans la première tranche de characterCount caractères, il sera de retour l'ensemble de la chaîne. Si vous préférez, il force un saut à $characterCount même si elle n'est pas une limite de mot, vous pouvez utiliser ceci:
Une dernière option, si vous voulez l'avoir ajouter des points de suspension s'il tronque la chaîne...
Description:
^
- début de début de chaîne([\s\S]{1,200})
- get de 1 à 200 de n'importe quel caractère[\s]+?
- de ne pas inclure d'espaces à la fin d'un court texte afin que nous puissions éviterword ...
au lieu deword...
[\s\S]+
- match, tous les autres contenusTests:
regex101.com
ajoutons àor
quelques autresr
regex101.com
orrrr
exactement 200 caractères.regex101.com
après la cinquièmer
orrrrr
exclus.Profiter.
$1
est un "remplacement", mais dans ce contexte précis, qu'est ce qu'il parle?? une variable vide?([\s\S]{1,200})
.$2
sera de référencement de deux deuxième paire de crochets s'il y a un motif.Je voudrais utiliser la fonction preg_match pour ce faire, comme ce que vous voulez est assez simple expression.
L'expression signifie "correspond à un sous-chaîne commençant à partir du début de la longueur de 1-200 qui se termine par un espace." Le résultat est dans $result, et le match est dans $matches. Qui prend soin de votre question initiale, qui est spécifiquement se terminant sur tout l'espace. Si vous souhaitez faire la fin sur les retours à la ligne, modifier l'expression régulière à:
Ok, donc j'ai eu une autre version de cette base sur les réponses ci-dessus, mais en prenant plus de choses en compte(utf-8, \n et   ; ), également une ligne de décapage de la shortcodes wordpress commenté si utilisé avec wp.
C'est un petit correctif pour mattmac réponse:
La seule différence est d'ajouter un espace à la fin de $chaine. Cela garantit que le dernier mot n'est pas coupé comme par ReX357 commentaire.
Je n'ai pas assez de points de rep pour ajouter un commentaire.
Utilisation:
Ce sera de sortie 10 premiers mots.
La
preg_split
fonction est utilisée pour découper une chaîne en sous-chaînes. Les limites le long de laquelle la chaîne est à diviser, sont spécifiés à l'aide d'une des expressions régulières modèle.preg_split
fonction prend 4 paramètres, mais seulement les 3 premiers sont pertinents pour nous maintenant.Premier Paramètre De Modèle
Le premier paramètre est les expressions régulières motif le long de laquelle la chaîne est fendue. Dans notre cas, nous voulons diviser la chaîne à travers les limites des mots. Par conséquent, nous utilisons une classe de caractères prédéfinis
\s
ce qui correspond à des caractères blancs (espace, tabulation, retour chariot et saut de ligne.Deuxième Paramètre D'Entrée De La Chaîne
Le deuxième paramètre est le long de la chaîne de texte que nous voulons partager.
Troisième Paramètre De Limite De
Le troisième paramètre indique le nombre de sous-chaînes qui doivent être renvoyés. Si vous définissez la limite de
n
, preg_split retournera un tableau de n éléments. La premièren-1
éléments contiennent les sous-chaînes. La dernière(n th)
élément contiendra le reste de la chaîne.Basé sur @Justin Poliey de la regex:
J'ai une fonction qui fait à peu près ce que vous voulez, si vous allez faire quelques modifications, il fit exactement:
C'est la façon dont je l'ai fait:
Je sais que c'est vieux, mais...
J'ai utilisé ce avant
J'ai créer une fonction de plus en plus semblables à substr, et en utilisant l'idée de @Dave.
Ps.: Toute la longueur de coupe peut être moins de substr.
Ajouté if/ELSEIF déclarations du code de Dave et AmalMurali pour la manipulation de chaînes de caractères sans espaces
Je trouve que cela fonctionne:
fonction abbreviate_string_to_whole_word($string,$max_length,$buffer) {
}
La mémoire tampon vous permet d'ajuster la longueur de la chaîne de retour.
Utiliser ceci:
le code suivant supprime ','. Si vous avez n'importe quelle autre caractère ou une sous-chaîne de caractères, vous pouvez utiliser à la place de ','
//si vous avez une autre chaîne de compte pour
Ici, vous pouvez essayer ce
Je crois que c'est la meilleure façon de le faire:
Je suis en utilisant les caractères spéciaux de scinder le texte et de le couper.
Peut-être cela va aider quelqu'un: