Tronquer un texte contenant du code HTML, en ignorant les tags
Je veux tronquer du texte (chargé à partir d'une base de données ou un fichier texte), mais il contient du HTML donc, en conséquence, les balises sont incluses et moins de texte sera renvoyé. Ceci peut causer des balises n'étant pas fermé ou partiellement fermé (si propre peut ne pas fonctionner correctement et il y a encore moins de contenu). Comment puis-je tronquer sur la base du texte (et probablement de s'arrêter lorsque vous arrivez à une table car cela pourrait causer plus de problèmes complexes).
substr("Hello, my <strong>name</strong> is <em>Sam</em>. I´m a web developer.",0,26)."..."
Dans
Hello, my <strong>name</st...
Ce que je veux c'est:
Hello, my <strong>name</strong> is <em>Sam</em>. I´m...
Comment puis-je faire cela?
Alors ma question est comment le faire en PHP, il serait bon de savoir comment le faire en C#... soit devrait être OK car je pense que je serais capable de port la méthode plus (sauf si c'est un construit dans la méthode).
Note aussi que j'ai inclus une entité HTML ´
- ce qui serait considéré comme un seul caractère (au lieu de 7 caractères, comme dans cet exemple).
strip_tags
est une solution de secours, mais je voudrais perdre la mise en forme et de liens, et il aurait toujours le problème avec les entités HTML.
OriginalL'auteur SamWM | 2009-07-28
Vous devez vous connecter pour publier un commentaire.
En supposant que vous utilisez XHTML valide, c'est simple à analyser le code HTML et assurez-vous que les balises sont correctement gérés. Il vous suffit de suivre les balises ont été ouverts à ce jour, et assurez-vous de fermer à nouveau "sur votre moyen de sortir".
Encodage note: Le code ci-dessus suppose que le XHTML est UTF-8 codé. Compatible ASCII codés sur un octet codages (comme Latin-1) sont également pris en charge, il suffit de passer
false
comme troisième argument. D'autres encodages multi-octets ne sont pas pris en charge, mais vous pouvez pirater le support en utilisantmb_convert_encoding
pour convertir en UTF-8 avant l'appel de la fonction, puis de les convertir dans tous lesprint
déclaration.(Vous devriez toujours être en UTF-8, si.)
Modifier: mise à Jour pour gérer les entités de caractères et encodage UTF-8. Correction d'un bug où la fonction serait d'imprimer un caractère de trop, si ce caractère est un caractère de l'entité.
Le code doit gérer des entités correctement maintenant.
Cela ne fonctionne pas avec des caractères internationaux parce que PHP preg_match compte par octet au lieu de caractère, pour l'offset. Pour voir l'essentiel de la solution: stackoverflow.com/questions/9950842/...
Merci pour cette remarque. Étant donné que j'ai moi-même toujours utiliser l'UTF-8, ce bug qui est un peu gênant. C'est corrigé dans le code maintenant (avec une autre comptage bug j'ai juste repéré).
la performance est exagéré ici
OriginalL'auteur Søren Løvborg
J'ai écrit une fonction qui tronque HTML comme yous suggèrent, mais au lieu d'imprimer les documents, il met juste en garde tout ça dans une variable de chaîne. poignées en Entités HTML, ainsi.
Merci @Matt! Je vais jeter un oeil depuis un bon moment, un écrit que peu de code.
Quelque peu limitée. "<div>des données est trop grande pour tenir dans le tronc de la taille</div>" de retour </div> à la place du texte jusqu'à le tronc de la taille. Est-ce un bug ou une fonctionnalité?
longtemps ici qui sera tronquée</div>', 10)) // => "<div>quelque chose de long…</div>" pas sûr de ce qu'il se passe dans votre cas. Notez comme il est, c'est une méthode de classe, sans classe. Afin de l'utiliser dans une configuration de test, je l'ai enlevé
public static
de la déclaration de la fonction. Je n'ai pas utilisé le PHP dans un certain temps maintenant.OriginalL'auteur alockwood05
Précis à 100%, mais assez difficile d'approche:
Simple force brute approche:
preg_split('/(<tag>)/')
avec PREG_DELIM_CAPTURE.html_entity_decode()
pour aider à mesurer avec précision).&[^\s;]+$
à la fin pour se débarrasser de peut-être haché entité)Est la force brute de la méthode que du mauvais? Première partie de cela peut être tout à fait précis (si vous êtes bon avec les expressions régulières), et avec bien Rangé, vous serez prise en charge HTML, les balises de début correctement (<table><tr><td></tbody></table> est valable HTML4 :), qui naïf de pile, la solution ne serait pas.
Si seulement quelqu'un pouvait donner un exemple de la précision de l'approche 🙁
Ne peut pas php de faire ce genre de manipulation en mode natif avec ses classes DOM sans la nécessité d'une nouvelle classe?? En jQuery, il me faudrait une demi-seconde, le programme de cette!
DOM du W3C a un certain soutien pour les plages et les itérateurs qui pourraient aider, mais je ne suis pas au courant d'une seule fonction spécifiquement pour la troncation. De même je ne pense pas que jQuery peut le faire correctement. Vous pouvez tronquer HTML dans un 1-liner, mais elle pourrait laisser ouverte entités ou de tronquer les attributs.
OriginalL'auteur Kornel
J'ai utilisé un joli fonction à http://alanwhipple.com/2011/05/25/php-truncate-string-preserving-html-tags-words, apparemment pris de CakePHP
OriginalL'auteur periklis
Ce qui suit est une simple machine d'état de l'analyseur qui s'occupe de vous de cas de test avec succès. J'échoue sur les balises imbriquées bien qu'il ne suit pas les balises elles-mêmes. J'ai aussi des bobines sur les entités à l'intérieur des balises HTML (par exemple dans un
href
-attribut d'un<a>
-tag). Il ne peut donc pas être considéré comme un 100% solution à ce problème, mais parce que c'est facile à comprendre, il pourrait être la base pour une plus avancés de la fonction.OriginalL'auteur Stefan Gehrig
Pourrait utiliser DomDocument dans ce cas, avec un méchant regex hack, le pire qui pourrait arriver est un avertissement, si il y a une fracture de la balise :
Devrait donner de sortie :
Hello, my <strong>**name**</strong>
.OriginalL'auteur
J'ai fait de légères modifications à Søren Løvborg
printTruncated
fonction rendant compatible UTF-8:OriginalL'auteur Bounce
Rebondir ajout de caractères multi-octets de soutien à Søren Løvborg de la solution - j'ai ajouté:
<hr>
,<br>
<col>
etc. n'obtenez pas fermé dans le HTML d'un '/' n'est pas nécessaire à la fin de celles-ci (dans l'est de XHTML si)),&hellips;
c'est à dire ... ),Tout cela à Pastie.
OriginalL'auteur hawkip
Une autre lumière des changements de Søren Løvborg printTruncated fonction rendant UTF-8 (Besoins mbstring) compatible et de le rendre chaîne de retour de ne pas imprimer une. Je pense que c'est plus utile.
Et mon code ne pas utiliser de tampon comme Rebondir variante, juste une variable.
UPD: pour le faire fonctionner correctement avec l'encodage utf-8 caractères dans les attributs de la balise, vous devez mb_preg_match fonction, énumérés ci-dessous.
Un grand merci à Søren Løvborg pour cette fonction, il est très bon.
OriginalL'auteur Andrey Nagikh
vous pouvez utiliser bien rangé ainsi:
OriginalL'auteur gpilotino
La CakePHP cadre a un HTML-connaissance truncate() fonction dans le TextHelper qui fonctionne pour moi. Voir Core-Helpers/Texte. Licence MIT.
OriginalL'auteur DavidJ
C'est très difficile de le faire sans l'aide d'un programme de validation et un analyseur syntaxique, la raison étant que, imaginez si vous avez
Comment envisagez-vous de tronquer et se retrouvent avec un code HTML valide?
Après une brève recherche, j'ai trouvé ce lien ce qui pourrait l'aider.
OriginalL'auteur Antony Carthy
Utiliser la fonction
truncateHTML()
à partir de:https://github.com/jlgrall/truncateHTML
Exemple: tronquer après 9 caractères, y compris les points de suspension:
Caractéristiques: UTF-8, configurable points de suspension, d'inclure ou d'exclure de la longueur de points de suspension, fermeture automatique des balises, l'effondrement des espaces, des éléments invisibles (
<head>
,<script>
,<noscript>
,<style>
,<!-- comments -->
), HTML$entities;
, tronquant au dernier mot en entier (avec l'option de toujours tronquer très long termes), PHP 5.6 et 7.0+, 240+ tests unitaires, retourne une chaîne de caractères (ne pas utiliser le tampon de sortie), et bien commenté code.J'ai écrit cette fonction, parce que j'ai vraiment aimé Søren Løvborg's de la fonction ci-dessus (en particulier la façon dont il a géré les codages), mais j'ai besoin d'un peu plus de fonctionnalités et de flexibilité.
OriginalL'auteur jlgrall