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 :

[BBCode]Regex pour html strict [RegEx]


Sujet :

Langage PHP

  1. #1
    Membre habitué
    Inscrit en
    Mai 2008
    Messages
    317
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 317
    Points : 135
    Points
    135
    Par défaut [BBCode]Regex pour html strict
    Bonjours à tous.

    J'ai un petit soucis de regex:
    J'ai un éditeur visuel qui créé du code html strict et j'ai besoin de transformer les balises que j'autorise en bbcode avant de supprimer toutes les autres balises html.

    --Toutes les balises BBcodes sont avec un espace supplémentaire pour ne pas être interprété par le forum; mais je suppose que vous vous en doutiez ^^--

    Passer de <b></b> à [ B][ /B] ou de <span style="font-weight:bold"></span> à [ B][ /B] c'est pas un problème mais là ou ça se complique:
    <span style="font-weight:bold; text-decoration:underline;"></span> à [ B][ U][ /B][ /U] ça commence à devenir la me***
    surtout sachant qu'il peut y avoir jusqu'à 3 style par span (B-U-I), et pas forcement dans cette ordre.
    Pour plus de clarté, voici un petit exemple généré par mon editeur (les 12 possibilité):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <span style="font-weight: bold; font-style: italic;">G-I</span><br>
    <span style="font-style: italic; font-weight: bold;">I-G</span><br>
    <span style="font-weight: bold; text-decoration: underline;">G-S</span><br>
    <span style="text-decoration: underline; font-weight: bold;">S-G</span><br>
    <span style="font-style: italic; text-decoration: underline;">I-S</span><br>
    <span style="text-decoration: underline; font-style: italic;">S-I</span><br>
    <span style="font-weight: bold; font-style: italic; text-decoration: underline;">G-I-S</span><br>
    <span style="font-weight: bold; text-decoration: underline; font-style: italic;">G-S-I</span><br>
    <span style="font-style: italic; font-weight: bold; text-decoration: underline;">I-G-S</span><br>
    <span style="font-style: italic; text-decoration: underline; font-weight: bold;">I-S-G</span><br>
    <span style="text-decoration: underline; font-weight: bold; font-style: italic;">S-G-I</span><br>
    <span style="text-decoration: underline; font-style: italic; font-weight: bold;">S-I-G<br></span>
    Pour le moment j'ai donc fais la regex que voici (je pensais faire 12 regex différente pour me simplifier la tâches):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $texte = preg_replace("#<span style=\"font-weight: bold; font-style: italic;\">(.+)</span>#","[ B][ I]$1[ /B][ I]", $texte);
    Problème: si on reprend mon exemple, la première balise est bien remplacée par [ B][ I]; par contre il remplace pas le bon </span>, c'est-celui de la dernière ligne qu'il remplace...
    Je peux même pas lui dire "prends le premier </span> etant donné qu'il peux y avoir un span dans le span ....
    Donc voila je bloque :S

    Si vous pouviez éclairer ma lanterne
    Merci d'avance.

  2. #2
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    Salut,

    Un truc dans ce genre peut-être une piste
    Code php : 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
     
    <?php
    $myPattern = '#<span style="([^"]++)">([^<]++)</span>#';
     
    // test
    $myString='<span style="font-weight: bold; font-style: italic;">G-I</span><br>';
    tst($myString);
    $myString='<span style="font-style: italic; font-weight: bold;">I-G</span><br>';
    tst($myString);
    $myString='<span style="font-weight: bold; text-decoration: underline;">G-S</span><br>';
    tst($myString);
    $myString='<span style="text-decoration: underline; font-weight: bold;">S-G</span><br>';
    tst($myString);
    $myString='<span style="font-style: italic; text-decoration: underline;">I-S</span><br>';
    tst($myString);
    $myString='<span style="text-decoration: underline; font-style: italic;">S-I</span><br>';
    tst($myString);
    $myString='<span style="font-weight: bold; font-style: italic; text-decoration: underline;">G-I-S</span><br>';
    tst($myString);
    $myString='<span style="font-weight: bold; text-decoration: underline; font-style: italic;">G-S-I</span><br>';
    tst($myString);
    $myString='<span style="font-style: italic; font-weight: bold; text-decoration: underline;">I-G-S</span><br>';
    tst($myString);
    $myString='<span style="font-style: italic; text-decoration: underline; font-weight: bold;">I-S-G</span><br>';
    tst($myString);
    $myString='<span style="text-decoration: underline; font-weight: bold; font-style: italic;">S-G-I</span><br>';
    tst($myString);
    $myString='<span style="text-decoration: underline; font-style: italic; font-weight: bold;">S-I-G<br></span>';
    tst($myString);
     
    function tst($myString) {
        global $myPattern;
        if (preg_match($myPattern, $myString, $matches)) {
            print_r($myString);
            $style = $matches[1];
            $content = $matches[2];
            if (preg_match('/text-decoration: underline/', $style))
                $content = "[U ]".$content."[ /U]";
            if (preg_match('/font-weight: bold/', $style))
                $content = "[B ]".$content."[ /B]";
            if (preg_match('/font-style: italic/', $style))
                $content = "[I ]".$content."[ /I]";
            print_r($content);
            print "<hr/>";
        }
    }
    Reste à remplacer le bon </span>, ce qui est un peu plus long à chercher.. Ca sent la fonction récursive à plein nez...

    Des liens en bonus

    http://php.developpez.com/faq/?page=...es_parsebbcode

    http://g-rossolini.developpez.com/tu...=page_3#LIII-6

  3. #3
    Membre confirmé Avatar de goodpz
    Profil pro
    Inscrit en
    Février 2007
    Messages
    475
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 475
    Points : 514
    Points
    514
    Par défaut
    Pour y arriver tu vas être obligé de passer par une "machine à états" et consumer la chaîne d'entrée de manière itérative. Il te faudrait une pile des "span" à fermer (donc en fait une combinaison de [/b ]|/[i ]|[/u ]) que tu "pop" à chaque </span>.

    Une version basée sur xsl/xpath 1.0 :
    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
     
    $xs = '<?xml version="1.0" encoding="utf-8"?'.'>'.<<<XSL
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" encoding="utf-8" indent="no" />
     <xsl:template match="/">
      <xsl:apply-templates/>
     </xsl:template>
     <xsl:template match="span">
      <xsl:if test="contains(@style,'bold')">[b ]</xsl:if>
      <xsl:if test="contains(@style,'italic')">[i ]</xsl:if>
      <xsl:if test="contains(@style,'underline')">[u ]</xsl:if>
      <xsl:apply-templates/>
      <xsl:if test="contains(@style,'underline')">[/u ]</xsl:if>
      <xsl:if test="contains(@style,'italic')">[/i ]</xsl:if>
      <xsl:if test="contains(@style,'bold')">[/b ]</xsl:if>
     </xsl:template>
     <xsl:template match="@*|node()">
      <xsl:copy>
       <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
     </xsl:template>
    </xsl:stylesheet>
    XSL;
    
    $h = new DOMDocument;
    $h->loadHTML($input); // $input est la chaîne à transformer
    $x = new DOMDocument;
    $x->loadXML($xs);
    $p = new XSLTProcessor;
    $p->importStyleSheet($x);
    echo htmlspecialchars($p->transformToXML($h));
    Ca se contente juste de transformer les <span>. Le reste est copié tel quel vers la sortie.

  4. #4
    Membre habitué
    Inscrit en
    Mai 2008
    Messages
    317
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 317
    Points : 135
    Points
    135
    Par défaut
    Merci pour ces deux réponses je vais aller voir tout ça.
    le script php est sympa, plus efficace que de faire 12 regex =)
    Le xml, peu pas dire sans tester, j'y connais pas grand chose.

    J'avais aussi l'idée de compter le nombre de balise entre les <span></span> afin de les refermer en conséquence;
    enfin je vous tiens au courant

  5. #5
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    J'avais oublié ce lien : une discussion que j'ai eu il y peu de temps

    http://www.developpez.net/forums/d66...back-recursif/

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. RegEx pour extraire les liens d'une page html
    Par herch dans le forum API standards et tierces
    Réponses: 7
    Dernier message: 13/05/2009, 17h26
  2. Regex pour vérifier la présence des tags HTML
    Par Benzeghiba dans le forum C#
    Réponses: 1
    Dernier message: 25/06/2008, 00h17
  3. Regex pour enlever les comments HTML
    Par pongping dans le forum Langage
    Réponses: 2
    Dernier message: 02/09/2007, 20h00
  4. [RegEx] regex pour remplacer bbcode et img
    Par gwena54 dans le forum Langage
    Réponses: 6
    Dernier message: 16/08/2007, 14h42

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