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 :

Besoin d'un coup de main pour écrire une regex [Fait] [RegEx]


Sujet :

Langage PHP

  1. #1
    Membre du Club Avatar de gaboo_bl
    Profil pro
    Inscrit en
    Août 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2006
    Messages : 67
    Points : 58
    Points
    58
    Par défaut Besoin d'un coup de main pour écrire une regex
    Bonjour à tous,

    j'ai besoin d'un coup de main pour écrire un masque dans preg_replace, je vous explique le problème:
    J'ai en entrant une chaîne contenant au moins une requête SQL. Cette chaine peut être multi lignes. Je voudrais, dans les clauses select ... from, remplacer les virgules qui séparent les colonnes par des ||, afin que la sortie de la requête dans sqlplus se fasse sur une ligne.
    Difficulté supplémentaire, il ne faut pas que les virgules qui se trouvent dans des parenthèses soient modifiées (car ce sont des séparateurs pour les paramètres de fonctions to_char(),...)
    J'ai déjà passé pas mal de temps dessus, mais je ne trouve pas: si quelqu'un à une idée...
    Je suis sur PHP 4.3.4 et Oracle 9.2.
    Merci

  2. #2
    Rédacteur
    Avatar de Yoshio
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    1 732
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 732
    Points : 2 853
    Points
    2 853
    Par défaut
    donne nous un exemple de la chaine a modifier et ce qu'elle devra etre apres modification


    Chaine originale :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT champ1, champ2, champ3 FROM table WHERE champ1='exemple'
    Chaine modifiée ?!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT champ1||champ2||champ3 FROM table WHERE champ1='exemple'
    C'est bien ca ?!

  3. #3
    Membre du Club Avatar de gaboo_bl
    Profil pro
    Inscrit en
    Août 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2006
    Messages : 67
    Points : 58
    Points
    58
    Par défaut
    Oui, c'est tout à fait çà, sauf que l'on peut aussi avoir des choses du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT champ1,
                 champ2, 
                 to_char(champ3,'YYYYMM'),
    From table 
    where champ1='exemple';
     
    select ...--une autre requête
    et que la chaine peut contenir plusieurs requêtes à la suite.
    J'ai omis de préciser que les mots clés peuvent en majuscule ou en minuscule, mais c'est parce que j'ai réglé ce problème avec l'option i.

  4. #4
    Rédacteur
    Avatar de Yoshio
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    1 732
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 732
    Points : 2 853
    Points
    2 853
    Par défaut
    Pour simpelment remplacer les virgule par || sans se soucier des fonctrion :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $str = preg_replace('`,([[:space:]])*`', '||', $str);
    Tu devrais l'avoir celui la lol (je continue a chercher pour l'autre)

  5. #5
    Membre du Club Avatar de gaboo_bl
    Profil pro
    Inscrit en
    Août 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2006
    Messages : 67
    Points : 58
    Points
    58
    Par défaut
    Oui ce morceau là fonctionne, je ne pensais pas que la classe :space: comprenait le retour chariot.
    Par contre je viens de m'apercevoir que j'ai oublié un point essentiel: Il arrive que j'ai des vues inline dans mes fichiers de requêtes, ce qui donne la syntaxe suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    select champ1,
    champ2
    from (SELECT champ1, champ2 from table) vue_inline, table2
    where 
    etc...
    et pour ces sous-requêtes, je ne dois pas changer les virgules par des ||.
    De même les virgules qui séparent les noms des tables ne doivent pas être remplacées.

    - Les vues inline nécessite automatiquement des parenthèses, donc si l'on trouve quelque chose pour éviter le remplacement dans les fonctions basé sur les parenthèses, y a de fortes chances pour que çà marche aussi dans ce cas,

    - pour la liste des tables, elle est toujours délimitée par from...where ou from...;
    Là c'est plus compliqué, je pense qu'il vaut mieux prendre la règle inverse:
    les virgules à remplacer sont encadrées par select...from

    En résumé mes règles de gestions sont:
    Remplacer toutes les virgules de la chaîne par ||:
    - qui se trouve quelque part entre un select et un from
    - qui ne se trouvent pas quelque part entre une parenthèse ouvrante et une parenthèse fermante.


    De quoi se donner mal au crâne, non?

  6. #6
    Rédacteur
    Avatar de Yoshio
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    1 732
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 732
    Points : 2 853
    Points
    2 853
    Par défaut
    Je pense pas que ca soit possible seulement avec des regex et preg_replace.

    Si c'est possible ca dépasse de loin mes compétence la dedans lol

    A la rigueur tu pourrais faire un explode() de ta chaine sur SELECT ... FROM. Et tu n'appliquerais que la le preg_replace. Apres tu fait un implode() pour revenir à la normal.

    EDIT : preg_split() plutot

  7. #7
    Rédacteur

    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 695
    Points : 1 071
    Points
    1 071
    Par défaut
    Une solution, en utilisant le Séparateur de requète, un code des sources présentes sur le site
    http://php.developpez.com/sources/


    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
    <?php
     
    function explode_parser( $str, $delimiter=',')
    {
        $len = strlen($str);
     
        for ($i = 0,$in_delimiter = true,$quote_is_begin = false,$tab = array(),$tmp = ''; $i < $len; $i++)
        {
            if ($str{$i} != $delimiter || ($quote_is_begin && $str{$i} == $delimiter))
            {
                if ($str{$i} == "(" && !$quote_is_begin)
                {
                    $quote_is_begin = TRUE;
                }
                else if ($str{$i} == ")" && $quote_is_begin && $str{$i - 1} != '\\')
                {
                    $quote_is_begin = FALSE;
                }
                $tmp .= $str{$i};
                $in_delimiter = FALSE;
            }
            else if ($str{$i} == $delimiter && !$in_delimiter && !$quote_is_begin)
            {
                $in_delimiter = TRUE;
                if (strlen($tmp) > 0)
                {
                    $tab[] = $tmp;
                }
                $tmp = '';
            }  
        }
     
        if (strlen($tmp) > 0)
        {
            $tab[] = $tmp;
        }
        return ($tab);
    }
     
     
    $q = "select champ1,
    champ2, to_char(champ3,'YYYYMM')
    from (SELECT champ1, champ2 from table) vue_inline, table2
    where ";
     
    $tabQ = array();
    preg_match("/^SELECT([a-zA-Z0-9_,\s()']+?)FROM/i", $q, $tabQ);
    $tabQ = explode_parser($tabQ['1'], ',');
     
    $tabQ = array_map('trim', $tabQ);
    $strQ = implode('||', $tabQ);
     
    $q = preg_replace("/^SELECT([a-zA-Z0-9_,\s()']+?)FROM/i", 'SELECT '.$strQ.' FROM', $q);
    echo $q;
    ?>

  8. #8
    Membre du Club Avatar de gaboo_bl
    Profil pro
    Inscrit en
    Août 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2006
    Messages : 67
    Points : 58
    Points
    58
    Par défaut
    OK, j'avais d'autre truc à résoudre cet aprés midi, et je n'ai pas eu le temps d'essayer çà. Il semble de toute façon qu'on obtienne le résultat voulu sans faire cette modif, je n'en aurais donc finalement pas besoin.
    Merci en tout cas à tous les deux pour vos réponses, je passe en résolu.

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

Discussions similaires

  1. [Bénévole] Besoin d'un coup de main pour faire une page web
    Par lefrangin dans le forum Autres
    Réponses: 0
    Dernier message: 12/10/2010, 23h17
  2. Réponses: 7
    Dernier message: 06/10/2010, 11h09
  3. Besoin d'un coup de main pour comprendre une formule
    Par teddyalbina dans le forum Mathématiques
    Réponses: 2
    Dernier message: 07/06/2009, 16h25
  4. besoin d'un coup de main pour une requête ;)
    Par Fabouney dans le forum Requêtes
    Réponses: 3
    Dernier message: 14/11/2005, 23h14

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