IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Couper correctement une chaine contenant du html


Sujet :

Langage PHP

  1. #1
    Membre éclairé
    Avatar de clavier12AZQSWX
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2009
    Messages
    1 423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 423
    Points : 874
    Points
    874
    Par défaut Couper correctement une chaine contenant du html
    bonjour,

    j'ai une page qui affiche une liste avec une colonne qui affiche une longue description formatée en html.

    par exemple :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    $description="<h2><strong>toto est <u>content</u></strong> enfin !!</h2>";

    admettons que je veuille n'afficher que 2 mots et remplacer la suite par "...";

    comment procéder ?
    à la base j'aurai fait un explode basé sur un espace pour connaître le dernier mot et ensuite sa position.
    seulement, mon reste de chaine a besoin des tag HTML de fin de balise pour rester affiché correctement !

    je ne peux pas avoir que
    "<h2><strong>toto est "
    il me faut : les tags de fermeture aussi
    <h2><strong>toto est </strong> </h2>"

    il y a bien la fonction wordwrap de php mais elle ne sait pas rajouter les tag html manquants non plus !
    je suis coincé...
    est-ce à moi de faire la compta des tags ouverts et de ajouter les manquants fermants ? n'y-a-t-il pas une fonction PHP qui "fix/corriger" le manque de tags fermants dans une chaine html ?
    Bien-entenndu , je ne peux pas faire de striptags au départ car j'ai besoin de la mise en forme....

    qu'en pensez-vous ?

  2. #2
    Membre expert
    Avatar de cavo789
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2004
    Messages
    1 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 785
    Points : 3 048
    Points
    3 048
    Par défaut
    Bonjour

    J'ai du mal à comprendre le besoin de couper du code HTML (ok, je comprends) mais aussi de l'afficher. Si tu coupes le code, c'est pour p.ex. l'afficher en mode "brut" (càd qu'on pourrait voir le code; pas son rendu).

    Ici, tu voudrais avoir une page HTML où tu afficherais, dans une colonne si j'ai bien compris, ici un code H2, là-bas une image, là-bas encore un texte, ...

    Si tu as un tag <img il pourrait être immensément long si le src n'est pas un fichier mais un code base64. Tu ferais quoi ? Couper comme tu le suggère et hop, c'est KO puisque tu ne peux pas te permettre de n'avoir que le début d'un code base64.

    Je pense que tu devrais donc afficher, non pas le rendu, mais le code html.

    Note (rien à voir avec ta question) : un tag h1, h2, ... ne devrait pas contenir de sous-tag. A quoi sert un "strong" dans un h2 ? Il suffit d'avoir un css où tu dis que h2 est bold:true. Un tag h2 ne devrait pas contenir un img non plus. Juste du texte; non ?

  3. #3
    Membre éclairé
    Avatar de clavier12AZQSWX
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2009
    Messages
    1 423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 423
    Points : 874
    Points
    874
    Par défaut
    J'ai du mal à comprendre le besoin de couper du code HTML
    j'ai une liste d'articles rédigés dans un format html formaté (avec des tags, des images..etc). je souhaite afficher de aperçus tronqués de cette liste et non pas la totalité dans la tableau. la partie tronquée sera remplacée par "...etc." afin d'inciter la personne à cliquer pour éditer/voir l'article complet. Je ne souhaite pas présenter la version textuelle mais garder la mise en forme (couleurs,gras,taille police...) de cette version listée.

  4. #4
    Membre actif Avatar de elcoyotos
    Homme Profil pro
    Amateur passionné
    Inscrit en
    Octobre 2006
    Messages
    490
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Amateur passionné

    Informations forums :
    Inscription : Octobre 2006
    Messages : 490
    Points : 294
    Points
    294
    Par défaut fonction couper texte html
    Salut,

    J'ai récupéré sur developpez.net il y a quelques années déjà cette fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
     
    <?php
    // ---------------------------------------------------
    // RÉSUMÉ d'un texte HTML : en fonction du NOMBRE de CARACTERES
    // + Réparation des balises HTML
    // ---------------------------------------------------
    // © Jérome Réaux : http://j-reaux.developpez.com - http://www.jerome-reaux-creations.fr
    // Création : juin 2009 en collectif : Xunil, jreaux62, s.n.a.f.u., FoxLeRenard, Doksuri, Patouche
    // http://www.developpez.net/forums/d757484-8/php/langage/contribuez/discussion-reparer-code-html/
    // ---------------------------------------------------
    // $texte : le texte formaté (avec des balises HTML)
    // $nbreCar : le nombre de caractères texte à afficher (sans compter les balises HTML)
    // $nbreCar (minimum) : pour ne pas couper un mot, le compte s'arrêtera à l'espace suivant
    // ---------------------------------------------------
    function couper_texte_html($texte, $nbreCar)
    {
     
        $nbreCarTexte = strlen($texte);
     
        if(is_numeric($nbreCar) and $nbreCarTexte > $nbreCar)
        {
            $PointSuspension        = '...'; // points de suspension (ou '' si vous n'en voulez pas)
            // ---------------------
            // longueur du texte brut, sans HTML (avant traitement)
            $LongueurAvantSansHtml    = strlen(trim(strip_tags($texte)));
            // ---------------------
            // MASQUE de l'expression régulière
            // ---------------------
            $MasqueHtmlSplit        = '#</?([a-zA-Z1-6]+)(?: +[a-zA-Z]+="[^"]*")*( ?/)?>#';
            $MasqueHtmlMatch        = '#<(?:/([a-zA-Z1-6]+)|([a-zA-Z1-6]+)(?: +[a-zA-Z]+="[^"]*")*( ?/)?)>#';
            // ---------------------
            // Explication du masque : recherche de TOUTES les balises HTML
            // ---------------
            // détail : </?([a-zA-Z1-6]+)
            // recherche de chaines commençant par un < 
            // suivi optionnellement d'un / (==> balises "fermantes")
            // suivi de (caractères alphabétiques (insensibles à la casse) ou numériques (1 à 6)) au moins une fois
            // Suivi optionnellement (0, 1 fois ou plus) par un ou plusieurs attributs et leur valeur :
            // ---------------
            // détail : (?: +[a-zA-Z]+="[^"]*")*
            // caractère espace une fois ou plus [space]+
            // suivi d'au moins un caractère alphabétique [a-zA-Z]+
            // suivi d'un =
            // suivi d'une paire de guillemets contenant optionnellement (0, 1 fois ou plus) tout caractère autre que guillemet "[^"]*"
            // ---------------
            // détail : ( ?/)?
            // caractère espace optionnel [space]?
            // suivi optionnellement d'un slash / (==> balises "orphelines")
            // NB : un :? suivant une parenthèse ouvrante signifie que l'on ne capture pas la parenthèse
     
            // ---------------------
            // RECHERCHE DU TEXTE DU RÉSUMÉ
            // ---------------------
            // ajout d'un espace de fin au cas où le texte n'en contiendrait pas...
            $texte                    .= ' ';
            // ---------------------
            // Capture de tous les bouts de texte (en dehors des balises HTML)
            $BoutsTexte                = preg_split($MasqueHtmlSplit, $texte, -1,  PREG_SPLIT_OFFSET_CAPTURE | PREG_SPLIT_NO_EMPTY);
            // ---------------------
            // Explication preg_split : voir http://fr.php.net/manual/fr/function.preg-split.php
            // => on obtient un tableau (array) :
            // $BoutsTexte[xx][0] : le bout de texte
            // $BoutsTexte[xx][1] : sa position (dans la chaine)
            // ---------------------
            // Nombre d'éléments du tableau
            $NombreBouts            = count($BoutsTexte);
     
            // ---------------------
            // CALCUL de la POSITION de la coupe
            // ---------------------
            // Si seulement un seul élément dans l'array, c'est que le texte ne contient pas de balises :
            // on renvoie directement le texte tronqué
            if( $NombreBouts == 1 )
            {
                $texte                .= ' ';
                $LongueurAvant        = strlen($texte);
                $texte                 = substr($texte, 0, strpos($texte, ' ', $LongueurAvant > $nbreCar ? $nbreCar : $LongueurAvant));
                if ($PointSuspension!='' && $LongueurAvant > $nbreCar) {
                    $texte            .= $PointSuspension;
                }
            } else {
                // ---------------------
                // Variable contenant la longueur des bouts de texte
                $longueur                = 0;
                // ---------------------
                // (position du dernier élément du tableau $chaines)
                $indexDernierBout        = $NombreBouts - 1;
                // ---------------------
                // Position par défaut de la césure au cas où la longueur du texte serait inférieure au nombre de caractères à sélectionner
                // La position de la césure est égale à sa position [1] + la longueur du bout de texte [0] - 1 (dernier caractère)
                $position                = $BoutsTexte[$indexDernierBout][1] + strlen($BoutsTexte[$indexDernierBout][0]) - 1;
                // ---------------------
                $indexBout                = $indexDernierBout;
                $rechercheEspace        = true;
                // ---------------------
                // Boucle parcourant l'array et ayant pour fonction d'incrémenter au fur et à mesure la longueur des morceaux de texte, 
                // et de calculer la position de césure de l'extrait dans le texte
                foreach( $BoutsTexte as $index => $bout )
                {
                    $longueur += strlen($bout[0]);
                    // Si la longueur désirée de l'extrait à obtenir est atteinte
                    if( $longueur >= $nbreCar )
                    {
                         // On calcule la position de césure du texte (position de chaîne + sa longueur -1 )
                         $position_fin_bout = $bout[1] + strlen($bout[0]) - 1;
                         // calcul de la position de césure
                         $position = $position_fin_bout - ($longueur - $nbreCar);
                         // On regarde si un espace est présent après la position dans le bout de texte
                         if( ($positionEspace = strpos($bout[0], ' ', $position - $bout[1])) !== false  )
                         {
                                // Un espace est détecté dans le bout de texte APRÈS la position
                                $position    = $bout[1] + $positionEspace;
                                $rechercheEspace = false;
                         }
                         // Si on ne se trouve pas sur le dernier élément
                         if( $index != $indexDernierBout )
                                $indexBout    = $index + 1;
                         break;
                    }
                }
                // ---------------------
                // Donc il n'y avait pas d'espace dans le bout de texte où la position de césure sert de référence
                if( $rechercheEspace === true )
                {
                    // Recherche d'un espace dans les bouts de texte suivants
                    for( $i=$indexBout; $i<=$indexDernierBout; $i++ )
                    {
                         $position = $BoutsTexte[$i][1];
                         if( ($positionEspace = strpos($BoutsTexte[$i][0], ' ')) !== false )
                         {
                                $position += $positionEspace;
                                break;
                         }
                    }
                }
                // ---------------------
                // COUPE DU TEXTE pour le RÉSUMÉ
                // ---------------------
                // On effectue la césure sur le texte suivant la position calculée
                $texte                    = substr($texte, 0, $position);
     
                // ---------------------
                // RECHERCHE DES BALISES HTML
                // ---------------------
                // Récupération de toutes les balises du texte et de leur position (PREG_OFFSET_CAPTURE)
                preg_match_all($MasqueHtmlMatch, $texte, $retour, PREG_OFFSET_CAPTURE);
                // ---------------------
                // Explication preg_match_all : voir http://fr.php.net/manual/fr/function.preg-match-all.php
                // $retour[0][xx][0] contient la balise HTML entière
                // $retour[0][xx][1] contient la position de la balise HTML entière
                // $retour[1][xx][0] contient le nom de la balise HTML fermante $rechercheEspace
                // $retour[2][xx][0] contient le nom de la balise HTML ouvrante
                // $retour[3][xx][0] contient le slash de fermeture de balise unique (cette variable n'existe pas si la balise n'est pas unique)
                // ---------------------
                // Array destiné à enregistrer les noms de balises ouvrantes
                $BoutsTag                = array();
                // ---------------------
                foreach( $retour[0] as $index => $tag )
                {
                    // Si on se trouve sur une balise unique, on passe au tour suivant
                    if( isset($retour[3][$index][0]) )
                    {
                         continue;
                    }
                    // Si le caractère slash n'est pas détecté en seconde position dans la balise entière, on est sur une balise ouvrante
                    if( $retour[0][$index][0][1] != '/' )
                    {
                         // On empile l'élément en début de l'array
                         array_unshift($BoutsTag, $retour[2][$index][0]);
                    }
                    // Donc balise fermante
                    else
                    {
                         // suppression du premier élément de l'array
                         array_shift($BoutsTag);
                    }
                }
                // ---------------------
                // RÉPARATION des balises HTML
                // ---------------------
                // Il reste des tags à fermer ?
                // balises ouvertes, mais non fermées : on ajoute les balises fermantes à la fin du texte
                if( !empty($BoutsTag) )
                {
                    foreach( $BoutsTag as $tag )
                    {
                         $texte        .= '</'.$tag.'>';
                    }
                }
                // ---------------------
                // On ajoute (ou pas) des points de suspension à la fin si le texte brut est plus long que $nbreCar
                if ($PointSuspension!='' && $LongueurAvantSansHtml > $nbreCar) {
                    // si les points de suspension sont après une(des) balise(s) fermante(s), 
                    // on les "remonte" jusqu'à l'intérieur de la balise non-vide la plus proche (ici jusqu'à 5 niveaux de balises).
                    // Explication du masque : ((</[^>]*>[\n\t\r ]*)?
                    // </[^>]*>            : toute balise fermante
                    // [\n\t\r ]*        : passage(s) à la ligne/tabulation(s)/espace(s)
                    $texte                .= 'ReplacePointSuspension';
                    $pattern            = '#((</[^>]*>[\n\t\r ]*)?(</[^>]*>[\n\t\r ]*)?(</[^>]*>[\n\t\r ]*)?(</[^>]*>[\n\t\r ]*)?(</[^>]*>)[\n\t\r ]*ReplacePointSuspension)#i';
                    $texte                = preg_replace($pattern, $PointSuspension.'${2}${3}${4}${5}${6}', $texte);
                }
            }
        }
        // ---------------------
        // On renvoie le résumé du texte correctement formaté.
        return $texte;
    };
    ?>
    Je pense que c'est ce que tu recherches...

Discussions similaires

  1. couper une chaine contenant plusieurs regex
    Par grospatapouf dans le forum Langage
    Réponses: 2
    Dernier message: 24/12/2008, 16h21
  2. [Oracle 10g] Insértion d'une chaine contenant " -- "
    Par 17mounir dans le forum Langage SQL
    Réponses: 5
    Dernier message: 13/02/2007, 15h50
  3. Formatter une chaine pour export HTML
    Par b_lob dans le forum C#
    Réponses: 1
    Dernier message: 06/02/2007, 14h49
  4. Réponses: 1
    Dernier message: 22/01/2007, 20h33
  5. passer d'une chaine contenant des espaces a un tableau
    Par flyfrog dans le forum Contribuez
    Réponses: 3
    Dernier message: 26/06/2006, 20h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo