[Réglé](Regex) Récupération d'une chaîne située entre deux mots

Récupération d'une chaîne située entre deux mots [Réglé] (Regex) - C#/.NET managed - Programmation

Marsh Posté le 15-04-2009 à 11:02:21    

Bonjour tous le monde,
je voudrais récupérer une chaîne de caractères dans un fichier texte.
 
La chaîne de caractère que je voudrai récupérer commence par ALTER TABLE et se finit par GO :

Code :
  1. ALTER TABLE [T_FA]  WITH CHECK ADD FOREIGN KEY([ID_MD])
  2. REFERENCES [T_MD] ([ID_MD])
  3. ON UPDATE CASCADE
  4. ON DELETE CASCADE
  5. GO


 
J'ai essayé plusieurs expressions régulières mais je ne trouve pas la bonne :(
 
J'ai trouvé celle-ci qui marche mais seulement si GO est sur la deuxième ligne ...

Code :
  1. Regex maregex = new Regex(@"ALTER TABLE(?<test>(.*)(\s*))GO" );


 
Comment faire pour que ma regex aille chercher le GO après plusieurs sauts de lignes ?


Message édité par 4rocky4 le 05-05-2009 à 13:25:41

---------------
- Un con qui marche ira plus loin qu'un intellectuel assis -
Reply

Marsh Posté le 15-04-2009 à 11:02:21   

Reply

Marsh Posté le 16-04-2009 à 01:11:31    

Pour des recherches sur plusieurs lignes, surcharges ton constructeur de regex avec "RegexOptions.Singleline", comme ça le "." match tout même les sauts de lignes, ce qui simplifie pas mal les choses.
 

Code :
  1. Regex taregex = new Regex(@"ALTER TABLE(?<test>.*)GO", RegexOptions.Singleline);


 
Si tu veut avoir la requête sql complète dans Groups["test"] :
 

Code :
  1. Regex taregex2 = new Regex(@"(?<test>ALTER TABLE.*GO)", RegexOptions.Singleline);

Reply

Marsh Posté le 16-04-2009 à 09:00:03    

Merci bien pour cette réponse, cependant une erreur peut se produire.
Admettons que ma chaîne de connexion est comme celle-ci (c'est le cas  :fou: ) :
 

Code :
  1. ALTER TABLE [T_AA]  WITH CHECK ADD FOREIGN KEY([ID_BB])
  2.    REFERENCES [T_BB] ([ID_BB])
  3.    ON UPDATE CASCADE
  4.    ON DELETE CASCADE
  5.    GO
  6.    ALTER TABLE [T_FA]  WITH CHECK ADD FOREIGN KEY([ID_MD])
  7.    REFERENCES [T_MD] ([ID_MD])
  8.    ON UPDATE CASCADE
  9.    ON DELETE CASCADE
  10.    GO


 
La regex va me renvoyer tout le contenu de cette chaîne au lieu de la couper en deux en s'arrêtant au premier "GO" ...


Message édité par 4rocky4 le 16-04-2009 à 11:28:26

---------------
- Un con qui marche ira plus loin qu'un intellectuel assis -
Reply

Marsh Posté le 16-04-2009 à 12:20:03    

Je t'ai répondu en fonction de ce qu'il y avait dans le premier message, je ne peut pas non plus deviner ce dont tu as besoin.
 
Donc tu veut récupérer pour chaque requête de "ALTER TABLE [NOM_DE_LA_TABLE]" jusqu'à "GO" ?
 
En voilà une qui peut le faire :
 

Code :
  1. Regex taregex = new Regex(@"(?<req>ALTER TABLE \[(?<table>[\w]*)\](.+\n)*\bGO\b)" );


 
Dans Groups["table"], tu récupère le nom de la table et dans Groups["req"], la requête complète.
 
Pour récupérer plusieurs requêtes, utilises un MatchCollection et parcours les Match avec un foreach par exemple.

Reply

Marsh Posté le 16-04-2009 à 13:23:41    

Effectivement, je ne l'avais pas précisé. Enfin je n'avais pas penser que cela pouvait se produire lol
 
Voilà comment j'ai fais :
 

Code :
  1. string chaine = @"ALTER TABLE [T_AA]  WITH CHECK ADD FOREIGN KEY([ID_BB])
  2. REFERENCES [T_BB] ([ID_BB])
  3. ON UPDATE CASCADE
  4. ON DELETE CASCADE
  5. GO
  6. ALTER TABLE [T_FA]  WITH CHECK ADD FOREIGN KEY([ID_MD])
  7. REFERENCES [T_MD] ([ID_MD])
  8. ON UPDATE CASCADE
  9. ON DELETE CASCADE
  10. GO";
  11. Regex maregex = new Regex(@"(?<req>ALTER TABLE \[(?<table>[\w]*)\](.+\n)*\bGO\b)" );
  12. MatchCollection matches = maregex.Matches(chaine);
  13. Match premiermatch = matches[0];
  14. Match secondmatch = matches[1];


 
lorsque j'exécute le code, permiermatch contient toujours tous les ALTER TABLE.
Cela commence du premier ALTER TABLE jusqu'au dernier GO.
 
Donc la ligne du secondmatch par en exception.
 
Ps : pour l'exemple j'ai mis deux ALTER TABLE mais en faite j'en ai une cinquantaine.


Message édité par 4rocky4 le 16-04-2009 à 13:52:23

---------------
- Un con qui marche ira plus loin qu'un intellectuel assis -
Reply

Marsh Posté le 16-04-2009 à 16:22:52    

OK donc il n'y a pas de ligne vide entre "GO" et "ALTER TABLE" alors ?
C'est normal que ça ne marche pas alors puisque j'avais basé la regex sur le fait que les GO et ALTER TABLE étaient séparés par une ligne vide (le fameux (.+\n)*).
 
C'est possible d'avoir plus de précision sur les ALTER TABLE (vu que tu en a une cinquantaine) ?
 
Ils sont toujours de la même forme ? :
ALTER TABLE [XXXX]  WITH CHECK ADD FOREIGN KEY([XXXX])
REFERENCES [XXXX] ([XXXX])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
 
Ou sinon ils ont toujours 5 lignes ?
 
En gros quels sont leurs points communs mis a part "ALTER TABLE" et "GO"


Message édité par Kormyr le 16-04-2009 à 16:25:46
Reply

Marsh Posté le 16-04-2009 à 16:40:17    

Les ALTER TABLE ne font pas toujours 5 lignes, ils varient suivant leur composition.
Ils s'enchainent tous les uns à la suite des autres comme ceci :
 

Code :
  1. ALTER TABLE [T2_REF_JDM]  WITH CHECK ADD FOREIGN KEY([ID_REF], [NUM_PROCESS])
  2. REFERENCES [T1_REF] ([ID_REF], [NUM_PROCESS])
  3. GO
  4. ALTER TABLE [T2_RESUL]  WITH CHECK ADD FOREIGN KEY([ID_PRODUIT])
  5. REFERENCES [T1_PRODUIT] ([ID_PRODUIT])
  6. GO
  7. ALTER TABLE [T2_REF_FAMILLE]  WITH CHECK ADD FOREIGN KEY([ID_REF], [NUM_PROCESS])
  8. REFERENCES [T1_REF] ([ID_REF], [NUM_PROCESS])
  9. ON UPDATE CASCADE
  10. ON DELETE CASCADE
  11. GO
  12. ALTER TABLE [T2_ROUTAGE] ADD  DEFAULT ((0)) FOR [CODE_DEFAUT]
  13. GO


 
Donc enfaite mon idée est d'isoler tous les ALTER TABLE pour par la suite les tester pour savoir si ils contiennent ON DELETE CASCADE.
Si ils en contiennent, je récupère le nom de la table et la ou les clefs primaires.
 
NORMALEMENT, le traitement est finit pour récupérer cela. Il faut juste que j'isole ces ALTER TABLE.


---------------
- Un con qui marche ira plus loin qu'un intellectuel assis -
Reply

Marsh Posté le 16-04-2009 à 16:53:03    

Bon, même si ça fait un peu rafistolage, essaie toujours celle là :
 

Code :
  1. Regex taregex = new Regex(@"(?<req>ALTER TABLE \[(?<table>[\w]*)\](.*\n){1,4}\bGO\b)" );


 
en gros avec le {1,4} on dit que le ALTER TABLE fait entre 2 et 5 lignes.


Message édité par Kormyr le 16-04-2009 à 16:54:49
Reply

Marsh Posté le 16-04-2009 à 17:02:57    

Cela semble bien me convenir  :)  
Merci bien !
 
Cependant, j'ai une dernière petite question.
Mon fichier contenant tous ces ALTER TABLE est créé automatiquement lors d'une migration de base de données.
Si dans les migrations futures, pour une raison que j'ignore, un ALTER TABLE fait 6 ou 7 lignes, je risque d'avoir une belle exception  :??:
 
Il faut que je crois les doigts pour la suite ou pas ? lol
 
Je ne sais pas comment la base va évoluer ...


---------------
- Un con qui marche ira plus loin qu'un intellectuel assis -
Reply

Marsh Posté le 16-04-2009 à 17:11:12    

suffit de rendre le . non greedy
 
ALTER.*?GO
 
plutot que d'utiliser des trucs trop compliqués

Reply

Marsh Posté le 16-04-2009 à 17:11:12   

Reply

Marsh Posté le 16-04-2009 à 17:16:42    

Je crois que j'ai un problème dans la récupération des premiers ALTER TABLE. Je regarde ça de plus prêt pour l'expliquer !
Brièvement déjà, ça me prend deux ALTER TABLE. Certainement un problème au niveau des lignes ...
 
Pour rendre le . non greedy, je fais la regex comme ça :

Code :
  1. Regex taregex = new Regex(@"(?<req>ALTER TABLE \[(?<table>[\w]*)\].*?\bGO\b)" );


?


---------------
- Un con qui marche ira plus loin qu'un intellectuel assis -
Reply

Marsh Posté le 16-04-2009 à 17:30:30    

une solution est trouvée :

Code :
  1. Regex("(ALTER TABLE)(.*?)(GO)", RegexOptions.Singleline)


C'est un peu la piste indiquée au début du post :)

Message cité 1 fois
Message édité par 4rocky4 le 16-04-2009 à 17:31:36

---------------
- Un con qui marche ira plus loin qu'un intellectuel assis -
Reply

Marsh Posté le 17-04-2009 à 03:00:33    

c'est bien t'as compris petit weakling
 
pour des questions a la con tu réfléchiras avant d'aller sur un forum
t'as clairement pas le niveau
si tu trouves pas la solution a ce probleme sans poser de question sur un forum, t'as aucun talent pour ce metier.
vas vendre des croissants tu ty retrouveras mieux

Message cité 1 fois
Message édité par djako666 le 17-04-2009 à 03:03:10
Reply

Marsh Posté le 17-04-2009 à 08:30:35    

Je ne vois pas du tout l'intérêt de tenir des propos offensifs comme cela ...
On peut très bien débuter dans un domaine et exceller dans un autre.
Alors la prochaine fois, avant de poster une réponse aussi idiote que celle-ci, pense à réfléchir !
 
ps : Vendeur de croissants est un métier comme un autre.


Message édité par 4rocky4 le 17-04-2009 à 08:33:40

---------------
- Un con qui marche ira plus loin qu'un intellectuel assis -
Reply

Marsh Posté le 17-04-2009 à 08:54:11    

djako666 a écrit :

c'est bien t'as compris petit weakling
 
pour des questions a la con tu réfléchiras avant d'aller sur un forum
t'as clairement pas le niveau
si tu trouves pas la solution a ce probleme sans poser de question sur un forum, t'as aucun talent pour ce metier.
vas vendre des croissants tu ty retrouveras mieux


Adieu [:papatte]


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 17-04-2009 à 11:24:56    

@djako666 : lol
 
Sinon tu as trouvé la solution ?
Tu as fait comment ?


Message édité par Kormyr le 17-04-2009 à 11:25:50
Reply

Marsh Posté le 20-04-2009 à 08:25:06    

4rocky4 a écrit :

une solution est trouvée :

Code :
  1. Regex("(ALTER TABLE)(.*?)(GO)", RegexOptions.Singleline)



 
C'est ce que tu me proposais au début mais certaines parenthèses supplémentaires étaient nécessaires.


---------------
- Un con qui marche ira plus loin qu'un intellectuel assis -
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed