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

C# Discussion :

(Expression régulière) Traitement d'un fichier txt


Sujet :

C#

  1. #1
    Membre habitué Avatar de 4rocky4
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    528
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 528
    Points : 180
    Points
    180
    Par défaut Gestion d'un fichier texte par tableau
    Bonjour tout le monde,

    Je travaille actuellement sur SharpDevelop pour créer un petit programme me permettant d'intervenir sur un fichier texte.
    Ce fichier texte contient uniquement des créations de tables et actuellement je bloque sur la création des séquences et triggers.

    Je m'explique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    CREATE TABLE T1_E (
      ID_E INTEGER  NOT NULL   IDENTITY ,
      NOM_E VARCHAR(32)  NOT NULL  ,
      T1_E_LIB INTEGER      ,
    PRIMARY KEY(ID_E));

    Dans mon fichier, je veux créer une séquence et un trigger pour chaque CREATE TABLE qui contient un IDENTITY.

    Pour cela, je dois récupérer le nom de la table ainsi que le nom du champ
    Dans l'exemple, je dois récupérer T1_E et ID_E.


    Il serait peut être mieux de répartir chaque CREATE dans un fichier texte pour traiter cela ... Je ne sais pas.

    Je commence à regarder les expressions régulières car je pense que c'est le moyen pour réaliser ce que je désire faire mais je voudrais bien qu'on m'éclaircisse un peu ...
    "J'glande pas ! Ça compile ..."

    4rocky4
    - Un con qui marche ira plus loin q'un intellectuel assis -

  2. #2
    Membre habitué Avatar de 4rocky4
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    528
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 528
    Points : 180
    Points
    180
    Par défaut
    L'expression régulière serait bien la solution je pense mais je n'arrive pas à récupérer le nom de la table et du champ.

    Pour le nom de la table, je pense qu'il faut se servir de la chaîne " CREATE TABLE" ainsi que des espaces (éventuellement la parenthèse qui suit).

    Et pour le champ je ne vois pas
    "J'glande pas ! Ça compile ..."

    4rocky4
    - Un con qui marche ira plus loin q'un intellectuel assis -

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    201
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 201
    Points : 196
    Points
    196
    Par défaut
    Salut,

    Les regex me semble être une solution viable, je pense que pour le nom de la table quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Regex finder = new Regex("CREATE TABLE (?<tableName>[A-Za-z0-9-_]+ \()");
    Et pour ta PK:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Regex finder = new Regex("PRIMARY KEY\((?<pkName>[A-Za-z0-9-_]+\))");

  4. #4
    Membre habitué Avatar de 4rocky4
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    528
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 528
    Points : 180
    Points
    180
    Par défaut
    Impeccable
    Cela m'est bien utile.

    J'te remercie
    "J'glande pas ! Ça compile ..."

    4rocky4
    - Un con qui marche ira plus loin q'un intellectuel assis -

  5. #5
    Membre habitué Avatar de 4rocky4
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    528
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 528
    Points : 180
    Points
    180
    Par défaut
    Je ne connaissais pas ce système de groupe.

    Deux petites questions encore

    à quoi correspond l'underscore ici ?
    Étant donné que mon fichier comporte plusieurs CREATE TABLE, est-il possible de récupérer seulement les noms pour les CREATE qui contiennent IDENTITY ?
    "J'glande pas ! Ça compile ..."

    4rocky4
    - Un con qui marche ira plus loin q'un intellectuel assis -

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    201
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 201
    Points : 196
    Points
    196
    Par défaut
    Citation Envoyé par 4rocky4 Voir le message
    à quoi correspond l'underscore ici ?
    En fait, c'est assez compliqué. Ca correspond à... un underscore . En fait ce n'est pas un caractère spécial. Et le tiret juste avant indique de la même manière, un tiret tout bête. En fait il n'y a pas de plage qui commence avant le tiret (vu que juste avant le 9, termine la plage '0-9').

    Citation Envoyé par 4rocky4 Voir le message
    Étant donné que mon fichier comporte plusieurs CREATE TABLE, est-il possible de récupérer seulement les noms pour les CREATE qui contiennent IDENTITY ?
    Là c'est plus dur je pense :/

    L'idéal à mon avis serai de faire une REGEX qui récupère toutes tes tables. Et ensuite pour chacune, de prendre le nom et l'identity si il y a.

  7. #7
    Membre habitué Avatar de 4rocky4
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    528
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 528
    Points : 180
    Points
    180
    Par défaut
    Merci bien pour les précisions

    Mon fichier contient 67 CREATE TABLE donc il faut que je puisse faire les triggers et séquences des CREATE qui contiennent IDENTITY.

    Je pensais avoir fait le plus dur en créant la séquence et le trigger automatiquement et qu'après ce n'était qu'une sorte de boucle à mettre en place. Apparemment j'me suis trompé

    Pour réaliser cela, la méthode serait de mettre chaque CREATE TABLE dans un nouveau fichier en récupérant la chaine "CREATE TABLE ...... ;"

    Puis après d'effectuer les triggers et séquences sur les fichiers qui contiennent un CREATE TABLE avec IDENTITY.


    Ou alors

    Isoler chaque bloc CREATE TABLE contenant IDENTITY et d'y faire le traitement de la dréation séquence et trigger.


    J'suis à la rue ou pas ? lol
    "J'glande pas ! Ça compile ..."

    4rocky4
    - Un con qui marche ira plus loin q'un intellectuel assis -

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    201
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 201
    Points : 196
    Points
    196
    Par défaut
    Citation Envoyé par 4rocky4 Voir le message
    Merci bien pour les précisions
    Pour réaliser cela, la méthode serait de mettre chaque CREATE TABLE dans un nouveau fichier en récupérant la chaine "CREATE TABLE ...... ;"
    Puis après d'effectuer les triggers et séquences sur les fichiers qui contiennent un CREATE TABLE avec IDENTITY.
    Pourquoi les mettre dans de nouveaux fichiers? autant les chargé en mémoire dans un tableau de string

    Amsi sinon c'est exactement ça, une fois chaque tables isolés, plus qu'a regarder sir leur déclaration contient Identity (avec un bête String.Contains()) et hop!

  9. #9
    Membre habitué Avatar de 4rocky4
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    528
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 528
    Points : 180
    Points
    180
    Par défaut
    D'accord, bon j'suis sur le bon chemin alors.
    j'me lance là dedans de suite.

    J'en ai pour un bon moment je pense car j'ai commencé C# depuis 2jours


    ps : Pour isoler les tables, je reste dans l'expression régulière ?
    "J'glande pas ! Ça compile ..."

    4rocky4
    - Un con qui marche ira plus loin q'un intellectuel assis -

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    201
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 201
    Points : 196
    Points
    196
    Par défaut
    Pour isoler les tables je te conseil:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Regex finder = new Regex("CREATE TABLE (?<createContent>[A-Za-z0-9-_,\(\)]+;");
    (je ne me souviens plus si il faut échapper les ',' et ';' par contre)

    Ensuite tu peux peut boucler sur tes groupes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    MatchCollection matches = finder.Matches(template);
    foreach (Match match in matches)
    {
        string statement = match.Groups["createContent"].value;
        if (statement.ToUpper().Contains("IDENTITY"))
        {
             //blablabla
        }
    }

  11. #11
    Membre habitué Avatar de 4rocky4
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    528
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 528
    Points : 180
    Points
    180
    Par défaut
    Impeccable alors si on peut boucler sur les groupes !
    je crois qu'on a pas besoin d'échapper les , et ;

    J'essaye ta méthode de suite !
    "J'glande pas ! Ça compile ..."

    4rocky4
    - Un con qui marche ira plus loin q'un intellectuel assis -

  12. #12
    Membre habitué Avatar de 4rocky4
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    528
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 528
    Points : 180
    Points
    180
    Par défaut
    Alors j'ai essayé de mettre en place cette méthode :

    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
     
    int cpt = 0;
    int cptfinal = 0;
     
    Regex finder = new Regex("CREATE TABLE (?<createContent>[A-Za-z0-9-_,\\(\\)]+);");
     
    MatchCollection matches = finder.Matches(texte);
    foreach (Match match in matches)
    {
        string statement = match.Groups["createContent"].Value;
        if (statement.ToUpper().Contains("IDENTITY"))
           {
               cpt = cpt +1;
        	}
    }
     
    cptfinal = cpt;

    Mais les compteurs restent à zéro .... J'ai fais une erreur ?

    Je crois qu'il faut mettre le + dans la parenthèse.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Regex finder = new Regex("CREATE TABLE (?<createContent>[A-Za-z0-9-_,\\(\\)]+);");
    A quoi correspond match de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    foreach (Match match in matches)

    match et statement restent Null quand je fais le pas à pas.
    "J'glande pas ! Ça compile ..."

    4rocky4
    - Un con qui marche ira plus loin q'un intellectuel assis -

  13. #13
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    201
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 201
    Points : 196
    Points
    196
    Par défaut
    MatchCollection contient tous les morceaux de texte qui vérifie l'expression de la Regex. Donc dans ton cas ma déclaration des "Create table".

    Mets un point d'arrêt avant le foreach et regarde ce que les méthodes te retourne tu devrais y apprendre beaucoup sur le soucis.

    EDIT:

    je viens de faire un test, le soucis viens de la regex. J'ai utilisé ça du coup:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Regex finder = new Regex(@"CREATE TABLE (?<createContent>[^;]+);");
    ça marche beaucoup mieux

  14. #14
    Membre habitué Avatar de 4rocky4
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    528
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 528
    Points : 180
    Points
    180
    Par défaut
    Effectivement cela va bien mieux

    Merci beaucoup pour ton aide
    "J'glande pas ! Ça compile ..."

    4rocky4
    - Un con qui marche ira plus loin q'un intellectuel assis -

  15. #15
    Membre habitué Avatar de 4rocky4
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    528
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 528
    Points : 180
    Points
    180
    Par défaut
    Peut-on m'expliquer le [^;] dans cette expression régulière :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Regex finder = new Regex(@"CREATE TABLE (?<createContent>[^;]+);");


    Si je veux récupérer uniquement le bloc FOREIGN KEY, je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Regex finder = new Regex(@"FOREIGN KEY (?<foreignkey>[^;]+);");
    Mais cela ne marche pas

    Par exemple dans ce CREATE TABLE, je voudrais récupérer les deux blocs FOREIGN KEY :

    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
    CREATE TABLE T2_A (
      ID_A INTEGER  NOT NULL   IDENTITY ,
      ID_R  NOT NULL  ,
      NUM_P SMALLINT  NOT NULL  ,
      NUM_L SMALLINT  NOT NULL    ,
    PRIMARY KEY(ID_A)    ,
      FOREIGN KEY(NUM_L)
        REFERENCES T1_L  (NUM_L)
          ON DELETE CASCADE
          ON UPDATE CASCADE,
      FOREIGN KEY(ID_R, NUM_P)
        REFERENCES T1_R(ID_R, NUM_P)
          ON DELETE CASCADE
          ON UPDATE CASCADE);
    J'ai certainement une erreur, c'est pourquoi je voudrai bien que l'on m'explique le bout d'expression régulière que je ne comprend pas

    Et j'ai une dernière question, comment je fais pour arrêter l'expression régulière soit à la virgule, soit au point virgule ? (Car si je m'arrête uniquement au point virgule, je n'aurais pas deux blocs FOREIGN KEY mais un seul.)

    Merci.
    "J'glande pas ! Ça compile ..."

    4rocky4
    - Un con qui marche ira plus loin q'un intellectuel assis -

  16. #16
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    201
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 201
    Points : 196
    Points
    196
    Par défaut
    Coucou

    [^;] => Signifie tout sauf ;
    Le ^ indique que tout les caractères du groupe (entre []), sont des caractères qu'on ne veut pas.

    Du coup, pour les Foreign key, hum..., c'est plus compliqué étant donné que des déclarations peuvent ce suivre, qu'elle peuvent contenir des , et qu'elle finisse par un ; ...

    A mon avis il faudrait une regex avec des conditions, là ça devient chaud...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Regex regex = new Regex(@"FOREIGN KEY\([^,)]+(([,][^)]+)?)\)[^(]+\([^,)]+(([,][^)]+)?)\)(([^,);]+)?)");
    Alors je vais essayer d'expliquer
    FOREIGN KEY\([^,)]+(([,][^)]+)?)\)[^(]+\([^,)]+(([,][^)]+)?)\)(([^,);]+)?)

    [^,)]+ : On commence par prendre une parenthèse, qu'on échappe avec '\'. Ensuite on prend tout ce qui suit sauf , et ). Le + indique qu'on veut au minimum 1 caractères.

    (([,][^)]+)?) : Alors ce bloc est optionnel, grâce au '?'. On veut 1 , et tout sauf ) ayant au moins 1 caractère. Ça nous permet de récupérer tout les champs de la FK.

    [^(] : Tout sauf parenthèse ouvrante, ça nous récupère le "REFERENCES".

    ([^,);]+)? : Et enfin on récupère la fin de FK et on arrète dès qu'on trouve une ',' ou ')' ou ';' .

    Et vala


    [EDIT] Il y a surement moyen de la simplifié mais là j'ai plus de neurone, (et j'ai pô le temps :p )

  17. #17
    Membre habitué Avatar de 4rocky4
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    528
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 528
    Points : 180
    Points
    180
    Par défaut
    Merci bien pour cette réponse ainsi que toutes ces explications

    Je pensais qu'il fallait utiliser encore les groupes.

    Je vais essayer ce que tu m'as expliqué
    "J'glande pas ! Ça compile ..."

    4rocky4
    - Un con qui marche ira plus loin q'un intellectuel assis -

  18. #18
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    201
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 201
    Points : 196
    Points
    196
    Par défaut
    Ha ben tu peux aussi y mettre des groupe hein . Mais j'en ai pas mis pour pas encore plus compliquer la chose.

    Faut savoir que les groupe servent juste à isoler les partie de ta regex dans une variable pour ensuite simplement cette partie de la regex.

  19. #19
    Membre habitué Avatar de 4rocky4
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    528
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 528
    Points : 180
    Points
    180
    Par défaut
    Pour chaque foreing key contenant "on update cascade", il va falloir que je créer un trigger pour remplacer on update cascade (ORACLE). Donc pour chaque bloc, je dois récupérer là ou les clefs étrangères.

    Donc j'ai bien peur d'être obligé d'utiliser les groupes non ?
    "J'glande pas ! Ça compile ..."

    4rocky4
    - Un con qui marche ira plus loin q'un intellectuel assis -

  20. #20
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    201
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 201
    Points : 196
    Points
    196
    Par défaut
    Soit tu fais des groupes, soit tu fais tout simplement un:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (Match.Value.Contains("On CASCADE")) { ... }
    Sinon pour les groupes, suffit de cibler le bloc qui t'interresse, tu l'entourre de parenthèses et juste après la parenthèse ouvrante tu met: ?<groupeName>.

    Et le tour est joué

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 5 12345 DernièreDernière

Discussions similaires

  1. Traitement d'un fichier txt
    Par anass_59 dans le forum Général Python
    Réponses: 15
    Dernier message: 23/06/2009, 11h13
  2. Expressions régulières : traitement de HtmlPage + API HtmlUnit
    Par lahmar.abdel1 dans le forum Général Java
    Réponses: 2
    Dernier message: 30/04/2009, 14h16
  3. traitement d'un fichier txt
    Par arezki76 dans le forum Shell et commandes GNU
    Réponses: 7
    Dernier message: 22/06/2007, 14h36
  4. Réponses: 9
    Dernier message: 03/01/2007, 17h06

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