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 :

Supprimer doublons et garder valeur [RegEx]


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    691
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2004
    Messages : 691
    Par défaut Supprimer doublons et garder valeur
    Bonjour

    j'ai un code html généré qui donne ca
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <span style="color:green;"><span style="font-size:14px;">
    Et je voudrais remplacer ce texte par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <span style="color:green;font-size:14px;">
    pour ceci j'utilise preg_replace avec une fonction que j'ai crée mais ca fonctionne pas vraiment enfin pas du tout

    mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    preg_replace('#(<span style="(.+?)">){1}(<span style="(.+?)">){1}#si','<span style="$1 $2">',$texte);
    Quelqu'un pourrait il maider à voir mon erreur merci.

    EDIT : j'ai oublié de préciser, ici je met deux span d'affilé mais ca peut etre 5 comme dix je connais pas le nombre exacte.

    J'ai reussi avec le code suivant à le faire fonctionner pour 2 span mais pas pour plus.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    preg_replace('#<span style="(.+?)"><span style="(.+?)">#si','<span style="$1 $2">',$texte);

  2. #2
    Membre expérimenté Avatar de daniel61
    Inscrit en
    Décembre 2006
    Messages
    139
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 139
    Par défaut
    un remplacement délicat peut être fait par preg_replace_callback() où il est possible de faire un sous traitement en php comme regex.

    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
     
    function span_replace($span) {
      if(preg_match_all('#style=["\'](.+?)["\']#',$span[0],$style)) {
        return '<span style="'.implode('',$style[1]).'">';
      }
      return $span[0];
    }
     
    $html='
    <span style="color:green;">
    <span style="font-size:14px;">
    <span style="background:yellow;">
    <span style="font-weight:bold;">
    ';
     
    $test=preg_replace_callback('#(?:<span style=["\'].+?["\']>\s*)+#','span_replace',$html);
    echo htmlentities($test);
    quant preg_replace_callback() rencontrera une séquence de <span style="...">, alors la fonction span_replace sera appellée pour joindre les styles en un seul span grâce à preg_match_all().

    même si j'ai testé le code qui précède, je pense que tu as oublié de dire ce que tu veux faire des </span> et des autres attributs des span... s'il y a d'autres attributs, mais l'idée est là avec preg_replace_callback().

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    691
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2004
    Messages : 691
    Par défaut
    En fait les </span> je les ai deja traité.

    Et comme ce code vient d'une mise en page d'un editeur je suis sur qu'il n'y aura a chaque fois qu'une seul attribut par span.

    Merci je vais tester ton code.


    EDIT: ca fonctionne nickel merci

    EDIT2 : Tu peux m'expliquer cette expression reguliere je la comprend pas tres bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #(?:<span style=["\'].+?["\']>\s*)+#

  4. #4
    Membre expérimenté Avatar de daniel61
    Inscrit en
    Décembre 2006
    Messages
    139
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 139
    Par défaut
    salut

    le point d'interrogation peut représenter 3 fonctions distinctes. il peut être un facteur de répétition pour dire 0 ou 1 fois, il n'est pas utiliser comme ça ici. par contre il est utiliser dans ses 2 autres formes.

    si le point d'interrogation est après une ouverture de parenthèse alors il indique que le caractère suivant sera une fonction à appliquer sur la parenthèse entière. (?:...) veut simplement dire de désactiver la possibilté de capture qui aurait été en \\1. la parenthèse (masque) est donc seulement utilisé comme regroupement de pattern, et le "+" suivant le masque veut dire de répéter 1 ou plusieurs fois le pattern complet. donc de prendre tous les <span...> consécutifs, par défaut il y a une capture en \\0 de la sous-chaine qui a satisfait l'expression entière, c'est seulement cette capture en \\0 que nous avons besoin. tu l'auras compris, ?: n'est pas obligatoire mais c'est une bonne habitude parcequ'il permet de prendre moins de mémoire, donc comme on a seulement besoin de \\0 et d'un regroupement pour pouvoir répéter le masque, j'ai utilisé ?: pour désactivé \\1 dans le tableau de résultats, ce qui n'est pas à négliger sur de grande quantité de données.

    lorsque le point d'interrogation est utilisé après un caractère de répétition, alors il permet de changer l'état greedy/ungreedy, par défaut c'est greedy (glouton) ici ["\'].+?["\'] veut dire de rechercher la séquence de 1 ou plusieurs caractères entre ' ou " en mode ungreedy (non glouton), donc dès qu'il rencontrera le premier caractère ' ou " il arrêtera, alors que greedy lui tenterait de rechercher le caractère ' ou " le plus loin possible.

    finalement, dans les autres contextes, le point d'interrogation veut dire de répéter 0 ou 1 fois... tu peux retrouver une expression qui pourrait utiliser le point d'interrogation dans ses 3 formes... (?:ba??)? voudrait dire de répéter le caractère "a" 0 ou 1 fois en mode ungreedy qui est précéder du caractère "b", de regrouper ce pattern en un masque non capturant et de répéter ce masque complet 0 ou 1 fois... pas très logique comme expression, m'enfin.

    il reste peut être à parler de \s*, \s est une classe de caractère qui représente les caractères blancs, qui sont 9-tab, 10-line feed/new line, 12-form feed, 13-carriage return et bien entendu 32-espace. "*" est le caractère de répétition pour 0 ou plusieurs fois. donc <span...><span...> est accepter, <span...> <span...> est accepter, les <span...> séparer par des retour à ligne sont aussi acceptés, et ainsi de suite.

    (?: masque de regroupement sans capture
    <span style= le pattern du masque commence par <span style=
    ["\'].+?["\'] puis tout caractère entre " ou ' et arrêter dès qu'un de ces 2 caractères est rencontré
    >\s* puis suivit de > et toute séquence de 0 ou plusieurs blancs
    ) fin du masque
    + et répéter le pattern dans le masque 1 ou plusieurs fois

    plusieurs fois peut être vu comme l'infini et je commencais à croire que j'allais écrire à l'infini aussi désolé si j'ai parlé de choses que tu connaissais déjà.

    par contre, je vois que j'ai oublié le cas de "background:url('aaa.jpg');" le code modifié est
    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
     
    function span_replace($span) {
      if(preg_match_all('#style=(["\'])(.+?)\1#',$span[0],$style)) {
        return '<span style="'.implode('',$style[2]).'">';
      }
      return $span[0];
    }
     
    $html=<<<test
    <span style="color:green;">
    <span style="font-size:14px;">
    <span style="background:yellow;">
    <span style="background:url('test.jpg');">
    <span style="font-weight:bold;">
    test;
     
    $test=preg_replace_callback('#(?:<span style=(["\']).+?\1>\s*)+#','span_replace',$html);
    echo htmlentities($test);
    bon... \1 est très simple, il réfère à la capture déjà fait en \\1, première parenthèse capturante, comme ça il pourrait y avoir des ' dans les " et inversement. désolé pour l'oubli

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

Discussions similaires

  1. [Toutes versions] Supprimer les doublons et garder un enregistrement
    Par Rodrigue dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 19/10/2012, 16h37
  2. Réponses: 5
    Dernier message: 17/08/2006, 15h45
  3. [SQL Serveur 2K] Procédure pour Supprimer doublons
    Par Vesta dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 29/05/2006, 12h32
  4. Réponses: 8
    Dernier message: 22/03/2006, 18h16
  5. [CR] doublon dans les valeurs
    Par Gaëtane dans le forum SAP Crystal Reports
    Réponses: 5
    Dernier message: 02/06/2004, 16h25

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