Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

CLASSE DE COUPAGE DE TEXTE HTML AVEC CONSERVATION DES BALISES


Information sur la source

Catégorie :Chaîne de caratère Classé sous : chaine, couper, balises, html, texte Niveau : Débutant Date de création : 24/01/2008 Date de mise à jour : 21/02/2008 11:19:24 Vu / téléchargé: 4 164 / 100

Note :
Aucune note

Commentaire sur cette source (5)
Ajouter un commentaire et/ou une note

Description

Bonjour,

Cette classe permet de couper une chaîne de caractère à une longueur donnée. La chaîne sera coupée entre deux mots et en dehors d'une balise.
Toutes les balises qui sont restées ouverte sont refermées à la fin de la chaîne.

Les balises ne sont pas exclues du calcul du nombre de caractères.
La classe gère les balises de type <br /> (qui n'ont qu'une seul balise).

Avec la généralisation des éditeurs wysiwyg qui retournent du texte html, ce genre de script devrait être de plus en plus rependu.

Exemple :

<p>Lorem ipsum <i>dolor</i> sit amet, <b>consec tetuer adipiscing elit</b></p>.

<p>Lorem ipsum <i>dolor</i> sit amet, <b>consec</b></p>
 

Source

  • <?php
  • class HtmlString {
  • /*
  • Chaine d'origine
  • */
  • private $strChaineOrigine;
  • /*
  • Chaine coupée à la longueur donnée
  • */
  • private $strChaineCoupee;
  • /*
  • Caractère ou doit se faire la césure
  • Par défaut, un espace
  • */
  • private $strCaractereCesure = ' ';
  • /*
  • Messages d'erreur
  • */
  • private $strErreur;
  • /*
  • Position de la césure
  • */
  • private $intCesurePos;
  • /*
  • Position du dernier espace de la chaine coupée
  • */
  • private $intDernierCaracCesure;
  • /*
  • Valeur de décrémentation de la taille de la chaine si on est dans une balise
  • */
  • private $intDecrementationCesurePos = 5;
  • /*
  • Indique si la césure est bien faite en dehors d'une balise
  • Par défaut on considère qu'elle est effectuée au milieu d'une balise
  • */
  • private $blnCesureHorsBalise = 0;
  • /*
  • Indique si la chaine est plus courte que la longueur de césure
  • Par défaut la chaine est plus longue
  • */
  • private $blnChaineTropCourte = 0;
  • /*
  • Pile des balises ouvertes
  • */
  • private $t_strBalisesOuvertes;
  • function __construct($strChaineOrigine, $intCesurePos) {
  • $this->strChaineOrigine = $strChaineOrigine;
  • $this->intCesurePos = $intCesurePos;
  • }
  • function SetParams($strCaractereCesure, $intDecrementationCesurePos) {
  • $this->strCaractereCesure = $strCaractereCesure;
  • $this->intDecrementationCesurePos = $intDecrementationCesurePos;
  • }
  • /*
  • Coupe la chaine d'origine au dernier espace avant la longueur voulue
  • */
  • private function CouperChaine(){
  • /* Coupe la chaine à la longuer maximale */
  • $this->strChaineCoupee = substr($this->strChaineOrigine, 0, $this->intCesurePos);
  • /* Extrait la position du dernier caractère de césure de la chaine coupée */
  • $this->intDernierCaracCesure = strrpos($this->strChaineCoupee, $this->strCaractereCesure);
  • /* Si le caractère de césure a été trouvé */
  • if($this->intDernierCaracCesure)
  • /* Coupe la chaine au dernier espace de sa longueur maximale */
  • $this->strChaineCoupee = substr($this->strChaineOrigine, 0, $this->intDernierCaracCesure);
  • }
  • /*
  • Vérifie que la césure n'aie pas été effectuée au milieu d'une balise
  • */
  • private function VerifierCesure() {
  • /* Parcours toute la chaine depuis la fin */
  • for($i=strlen($this->strChaineCoupee)-1; $i>=0; $i--) {
  • /* Si on tombe sur une fermeture de balise */
  • if($this->strChaineCoupee[$i] == '>' && $this->strChaineCoupee[$i-1] != '\\') {
  • /* Alors on est pas dans une balise */
  • $this->blnCesureHorsBalise = 1;
  • break;
  • }
  • /* Si on tombe sur une ouverture de balise, alors on est dans une balise */
  • elseif($this->strChaineCoupee[$i] == '<' && $this->strChaineCoupee[$i-1] != '\\') {
  • /* On le respécifie même si la valeur est censée être à 0 */
  • $this->blnCesureHorsBalise = 0;
  • break;
  • }
  • /* Si c'est le premier caractère de la chaine */
  • if($i==0)
  • /* Alors c'est qu'il n'y avait pas de balises du tout */
  • $this->blnCesureHorsBalise = 1;
  • }
  • }
  • /*
  • Vérifie que la chaine soit plus longue que la position de césure
  • */
  • private function VerifierLongueurChaine(){
  • /* Si la chaine est vide */
  • if(strlen($this->strChaineOrigine) == 0)
  • /* Indiquer que la chaine est trop courte */
  • $this->blnChaineTropCourte = 1;
  • /* Si la chaine est plus petite que la position de césure */
  • elseif(strlen($this->strChaineOrigine) <= $this->intCesurePos)
  • /* Indiquer que la chaine est trop courte */
  • $this->blnChaineTropCourte = 1;
  • /* Si la chaine est plus grande */
  • else
  • /* Indiquer que la chaine n'est pas trop courte */
  • $this->blnChaineTropCourte = 0;
  • }
  • /*
  • Obtient la chaine coupée à un espace en dehors d'une balise
  • */
  • private function ObtenirChaineCoupeeJuste() {
  • /* Tant que la césure n'est pas effectuée en dehors d'une balise */
  • while(!$this->blnCesureHorsBalise) {
  • /* Couper la chaine */
  • $this->CouperChaine();
  • /* Réduire la longueur de la chaine coupée */
  • if($this->intCesurePos - $this->intDecrementationCesurePos >= 0) {
  • $this->intCesurePos -= $this->intDecrementationCesurePos;
  • }
  • /* Si on a réduit la position de césure au point de couper toute la chaine, on affiche une erreur */
  • /* Peut arriver si la position de césure est courte et qu'il y a une très longue balise au début */
  • else {
  • $this->strErreur = 'Erreur : la position de la césure est trop courte par rapport à la taille de la chaine.';
  • break;
  • }
  • $this->VerifierCesure();
  • }
  • }
  • private function TrouverBalises() {
  • /* Place toutes les balises ouvrantes dans un tableau */
  • $strBalisesOuvrantes = preg_match_all('|<([a-z]+)[^>]*>|i', $this->strChaineCoupee, $t_strBalisesOuvrantes);
  • /* Place le résultat dans le tableau de la classe */
  • $this->t_strBalisesOuvertes = $t_strBalisesOuvrantes[1];
  • /* Place toutes les balises fermantes dans un tableau */
  • $strBalisesFermantes = preg_match_all('|</([a-z]+)[^>]*>|i', $this->strChaineCoupee, $t_strBalisesFermantes);
  • /* Inverse le tableau des balises ouvrantes (vu qu'elles doivent se fermer en ordre inverse) */
  • $this->t_strBalisesOuvertes = array_reverse($this->t_strBalisesOuvertes);
  • /* Parcours le tableau des balises fermantes */
  • foreach($t_strBalisesFermantes[1] as $Index => $strBaliseFermante) {
  • /* Parcours le tableau des balises ouvrantes */
  • foreach($this->t_strBalisesOuvertes as $Index => $strBaliseOuvrante) {
  • /* Si le nom de la balise est identique */
  • if($strBaliseOuvrante == $strBaliseFermante) {
  • /* Supprime la balise de la liste des balises ouvrantes */
  • unset($this->t_strBalisesOuvertes[$Index]);
  • break;
  • }
  • }
  • }
  • }
  • private function FermerBalises() {
  • /* Pour chaque balise ouverte restante */
  • foreach($this->t_strBalisesOuvertes as $strBaliseOuverte)
  • /* Ferme la balise */
  • $this->strChaineCoupee .= '</' . $strBaliseOuverte . '>';
  • }
  • public function ExecuterCoupe() {
  • $this->VerifierLongueurChaine();
  • if(!$this->blnChaineTropCourte) {
  • $this->ObtenirChaineCoupeeJuste();
  • $this->TrouverBalises();
  • $this->FermerBalises();
  • $strRetour = $this->strChaineCoupee;
  • }
  • else {
  • $strRetour = $this->strChaineOrigine;
  • }
  • if(strlen($this->strErreur) > 2)
  • return $this->strErreur;
  • else
  • return $strRetour;
  • }
  • }
  • ?>
<?php
class HtmlString {
	
	/*
	Chaine d'origine
	*/
	private $strChaineOrigine;
	
	/*
	Chaine coupée à la longueur donnée
	*/
	private $strChaineCoupee;
	
	/*
	Caractère ou doit se faire la césure
	Par défaut, un espace
	*/
	private $strCaractereCesure = ' ';
	
	/*
	Messages d'erreur
	*/
	private $strErreur;
	
	/*
	Position de la césure
	*/
	private $intCesurePos;
	
	/*
	Position du dernier espace de la chaine coupée
	*/
	private $intDernierCaracCesure;
	
	/*
	Valeur de décrémentation de la taille de la chaine si on est dans une balise
	*/
	private $intDecrementationCesurePos = 5;
	
	/*
	Indique si la césure est bien faite en dehors d'une balise
	Par défaut on considère qu'elle est effectuée au milieu d'une balise
	*/
	private $blnCesureHorsBalise = 0;
	
	/*
	Indique si la chaine est plus courte que la longueur de césure
	Par défaut la chaine est plus longue
	*/
	private $blnChaineTropCourte = 0;
	
	/*
	Pile des balises ouvertes
	*/
	private $t_strBalisesOuvertes;
	
	function __construct($strChaineOrigine, $intCesurePos) {
		$this->strChaineOrigine = $strChaineOrigine;
		$this->intCesurePos = $intCesurePos;
	}
	
	function SetParams($strCaractereCesure, $intDecrementationCesurePos) {
		$this->strCaractereCesure = $strCaractereCesure;
		$this->intDecrementationCesurePos = $intDecrementationCesurePos;
	}
	
	/*
	Coupe la chaine d'origine au dernier espace avant la longueur voulue
	*/
	private function CouperChaine(){
		/* Coupe la chaine à la longuer maximale */
		$this->strChaineCoupee = substr($this->strChaineOrigine, 0, $this->intCesurePos);
		/* Extrait la position du dernier caractère de césure de la chaine coupée */
		$this->intDernierCaracCesure = strrpos($this->strChaineCoupee, $this->strCaractereCesure);
		
		/* Si le caractère de césure a été trouvé */
		if($this->intDernierCaracCesure)
			/* Coupe la chaine au dernier espace de sa longueur maximale */
			$this->strChaineCoupee = substr($this->strChaineOrigine, 0, $this->intDernierCaracCesure);
	}
	
	/*
	Vérifie que la césure n'aie pas été effectuée au milieu d'une balise
	*/
	private function VerifierCesure() {

		/* Parcours toute la chaine depuis la fin */
		for($i=strlen($this->strChaineCoupee)-1; $i>=0; $i--) {

			/* Si on tombe sur une fermeture de balise */
			if($this->strChaineCoupee[$i] == '>' && $this->strChaineCoupee[$i-1] != '\\') {
				/* Alors on est pas dans une balise */
				$this->blnCesureHorsBalise = 1;
				break;
			}
			/* Si on tombe sur une ouverture de balise, alors on est dans une balise */
			elseif($this->strChaineCoupee[$i] == '<' && $this->strChaineCoupee[$i-1] != '\\') {
				/* On le respécifie même si la valeur est censée être à 0 */
				$this->blnCesureHorsBalise = 0;
				break;
			}
			
			/* Si c'est le premier caractère de la chaine */
			if($i==0)
				/* Alors c'est qu'il n'y avait pas de balises du tout */
				$this->blnCesureHorsBalise = 1;
		}
	}
	
	/*
	Vérifie que la chaine soit plus longue que la position de césure
	*/
	private function VerifierLongueurChaine(){
		/* Si la chaine est vide */
		if(strlen($this->strChaineOrigine) == 0)
			/* Indiquer que la chaine est trop courte */
			$this->blnChaineTropCourte = 1;
		/* Si la chaine est plus petite que la position de césure */
		elseif(strlen($this->strChaineOrigine) <= $this->intCesurePos)
			/* Indiquer que la chaine est trop courte */
			$this->blnChaineTropCourte = 1;
		/* Si la chaine est plus grande */
		else
			/* Indiquer que la chaine n'est pas trop courte */
			$this->blnChaineTropCourte = 0;
	}
	
	/*
	Obtient la chaine coupée à un espace en dehors d'une balise
	*/
	private function ObtenirChaineCoupeeJuste() {
		/* Tant que la césure n'est pas effectuée en dehors d'une balise */
		while(!$this->blnCesureHorsBalise) {
			/* Couper la chaine */
			$this->CouperChaine();

			/* Réduire la longueur de la chaine coupée */
			if($this->intCesurePos - $this->intDecrementationCesurePos >= 0) {
				$this->intCesurePos -= $this->intDecrementationCesurePos;
			}
			/* Si on a réduit la position de césure au point de couper toute la chaine, on affiche une erreur */
			/* Peut arriver si la position de césure est courte et qu'il y a une très longue balise au début */
			else {
				$this->strErreur = 'Erreur : la position de la césure est trop courte par rapport à la taille de la chaine.';		
				break;
			}
			$this->VerifierCesure();
		}
	}
	
	private function TrouverBalises() {
		
		/* Place toutes les balises ouvrantes dans un tableau */
		$strBalisesOuvrantes = preg_match_all('|<([a-z]+)[^>]*>|i', $this->strChaineCoupee, $t_strBalisesOuvrantes);		
		
		/* Place le résultat dans le tableau de la classe */
		$this->t_strBalisesOuvertes = $t_strBalisesOuvrantes[1];
		
		/* Place toutes les balises fermantes dans un tableau */
		$strBalisesFermantes = preg_match_all('|</([a-z]+)[^>]*>|i', $this->strChaineCoupee, $t_strBalisesFermantes);	
		
		/* Inverse le tableau des balises ouvrantes (vu qu'elles doivent se fermer en ordre inverse) */
		$this->t_strBalisesOuvertes = array_reverse($this->t_strBalisesOuvertes);
		
		/* Parcours le tableau des balises fermantes */
		foreach($t_strBalisesFermantes[1] as $Index => $strBaliseFermante) {
			/* Parcours le tableau des balises ouvrantes */
			foreach($this->t_strBalisesOuvertes as $Index => $strBaliseOuvrante) {
				/* Si le nom de la balise est identique */
				if($strBaliseOuvrante == $strBaliseFermante) {
					/* Supprime la balise de la liste des balises ouvrantes */
					unset($this->t_strBalisesOuvertes[$Index]);
					break;
				}
			}
		}
	}
	
	private function FermerBalises() {
		/* Pour chaque balise ouverte restante */
		foreach($this->t_strBalisesOuvertes as $strBaliseOuverte)
			/* Ferme la balise */
			$this->strChaineCoupee .= '</' . $strBaliseOuverte . '>';
	}
	
	public function ExecuterCoupe() {
		$this->VerifierLongueurChaine();
		
		if(!$this->blnChaineTropCourte) {
			$this->ObtenirChaineCoupeeJuste();
			$this->TrouverBalises();
			$this->FermerBalises();
			$strRetour = $this->strChaineCoupee;
		}
		else {
			$strRetour = $this->strChaineOrigine;
		}
		
		if(strlen($this->strErreur) > 2)
			return $this->strErreur;
		else
			return $strRetour;
	}
}

?>

Conclusion

Il y a encore beaucoup d'améliorations à y apporter, dans la gestion des caractères échappés par exemple (\< ne doit pas être considéré comme balise si magic_quotes est activé)

C'est mon premier script en php orienté objet, donc il y a sûrement pas mal de choses a améliorer, n'hésitez surtout pas à faire des critiques.
 

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

Historique

24 janvier 2008 12:31:15 :
Exemple d'application
21 février 2008 11:19:24 :
Première modification ou une partie du script travaille maintenant avec des regex pour accélérer l'exécution.

Commentaires et avis

signaler à un administrateur
Commentaire de LaurentKOogar le 25/01/2008 09:31:34

c'est rigolo comme code, ca doit pouvoir se faire avec une expression regulières en 5 lignes mais c'est rigolo comme code ^^

signaler à un administrateur
Commentaire de Bloodscalp le 25/01/2008 16:35:23

Et ben montre moi seulement, y'a surement à racourcir j'en doute pas mais faire une remarque comme ça sans rien proposer, c'est pas très constructif...

signaler à un administrateur
Commentaire de LaurentKOogar le 25/01/2008 21:02:06

va faire un tour du coté des fonctions PCRE en utilisant des masques de ce type:
$masque = '#(<[a-zA-Z]+>).*?(</[a-zA-Z]+>)#si';
1° prend toute les balises et met les dans un tableau pour les indicer et pourvoir les comparer.
2° decoupe ta chaine en 2 et travaille sur la partie tronqué et non tronqué
3° tronque en rajoutant tes balises
4° encore trop long ? -> rapel (récursif) la fonction

PS: et oublie tres vite les substr et strpos pour ce genre d'application. Ces fonctions sont des vrais boulets en temps machine et offre vraiment des possibilités tres reduites de developpement. Tu devrais t'eclater 100 fois plus avec les PCRE

Enjoy ;)

signaler à un administrateur
Commentaire de olid le 28/01/2008 02:34:02

Excellente initiative, je n'avais pas eu le courage de m'y mettre.

Je te propose le défis d'appliquer ma méthode qui préserve les mots et les phrases quand on résume :
http://www.phpcs.com/codes/RESUMER-TEXTE-SANS-COUPER-MOTS-PHRASES_40147.aspx

Bonne continuation :o)

signaler à un administrateur
Commentaire de Bloodscalp le 30/01/2008 15:22:20

Merci LaurentKOogar, je ferais une nouvelle version qui utiliseras des regex pour trouver les balises, ceci dès que j'aurais un peu de temps libre.

Olid, j'ai regardé ta classe et il me semble que la seule amélioration pertinente soit la possibilité de couper la chaîne à un point (fin de phrase). Pourquoi pas, ça peu toujours être utile.

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

Supprimer les balises html d'une chaine de caractère [ par SAaD44 ] Salut !Voila, je cherche le moyen de supprimer toutes les balises html (de début et de fin) d'une chaine de caractère.Merci d'avance SAâD supprimer le contenu des balises script [ par caviar ] Saluté ...j'ai un petit casse tête à résoudre ...j'aimerai filtrer les balises scripts dans un code html et les supprimerimaginon que j'ai en html ava Remplacer   [ par pcgpegase ] Bonjour,Je vous expose mon problème :J'ai un champs de type TEXT dans ma base MySQL qui contient donc du texte !Quand je fais afficher ce texte, c'est decoupe de chaine [ par atchoumen ] Bonjour,V'la je suis bloquer sur un problème  un peu débile donc je fais appel a vous. Voici le code :&lt;? $nb_car = 900;  $montexte = $enregistremen Couper une chaine tous les X mots [ par 3xodius55 ] Bonjour (ou re-bonjour pour quelques uns^^),Est-ce que vous sauriez par hasard comment je pourrai couper une chaine tous les X mots.La chaîne en quest Recuperer des informations d'une fichier xml [ par dbzonline ] salut tous , alors j'ai une petite question j'ai recupéré un code disponible sur le site pour generer une image avec du texte , je l'ai adapté et main Supprimer les balises html [ par ImmortalPC ] Salut,J'aimerai savoir comment faire pour supprimer tout les balises &#233;ventuelle et ne garder que le texte tout cela dans une varriable ou plusieu Redimensionner une image entre deux balises [ par thecomputerman ] Bonjour,J'ai un petit soucis avec le redimensionnement d'images. Tout d'abord quand une image est insérée dans un texte c'est entre deux balises [img] Calculer le contenu d'une chaine de texte [ par dragon ] Bonjour à tous,j'aimerais me créé un BBCode pour mon forum qui serait capapble de faire des calculs simples (+,-,*,/). J'aimerais savoir s'il existe u pb mail html [ par Diablo62 ] bonjour je suis en train de faire des tests d'envoie de mail en html et txt mais cela ne marche pas apparament sur homail j ai un mail vide et sur out


Nos sponsors

Sondage...

CalendriCode

Janvier 2009
LMMJVSD
   1234
567891011
12131415161718
19202122232425
262728293031 

Consulter la suite du CalendriCode

Téléchargements

Logiciels à télécharger sur le même thème :



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel BAÏSE, Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 1,201 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.