2009-03-12 7 views
1

J'apprends l'expression rationnelle et j'ai besoin d'aide pour obtenir toutes les correspondances possibles pour un motif d'une chaîne.Regex pour obtenir toutes les correspondances possibles pour un modèle en C#

Si mon entrée est:

case a 
when cond1 
then stmt1; 
when cond2 
then stmt2; 
end case; 

J'ai besoin pour obtenir les résultats qui ont des groupes comme suit

Groupe1:

  1. "cond1"
  2. "stmt1;"

et Group2:

  1. "cond2"
  2. "stmt2;"

Est-il possible d'obtenir de tels groupes en utilisant une expression rationnelle?

+0

Je ne pense pas comprendre. Quel est votre code à utiliser avec les regex? – Grzenio

+0

Je pensais qu'il serait plus facile d'obtenir toutes ces boucles/blocs en utilisant regex au lieu de les traiter par le biais de la programmation traditionnelle. De plus, je peux utiliser une telle regex pour analyser de nombreuses structures différentes. – Archie

+0

Je pense que vous devriez écrire un analyseur, l'analyse du code source avec des expressions régulières seul ne fonctionnera pas. – Tomalak

Répondre

6

Il est possible d'utiliser regex pour cela à condition de ne pas imbriquer vos instructions. Par exemple si votre stmt1 est une autre déclaration de cas, alors tous les paris sont désactivés (vous ne pouvez pas utiliser regex pour quelque chose comme ça, vous avez besoin d'un analyseur régulier).

Modifier: Si vous voulez vraiment essayer, vous pouvez le faire avec quelque chose comme (non testé, mais vous voyez l'idée):

Regex t = new Regex(@"when\s+(.*?)\s+then\s+(.*?;)", RegexOptions.Singleline) 
allMatches = t.Matches(input_string) 

Mais comme je le disais cela ne fonctionnera que pour ne pas déclarations imbriquées.

Édition 2: Modification de l'expression régulière pour inclure le point-virgule dans le dernier groupe. Cela ne fonctionnera pas comme vous le vouliez - à la place, il vous donnera plusieurs correspondances et chaque correspondance représentera un lorsque la condition, avec le premier groupe de la condition et la seconde groupe la déclaration.

Je ne pense pas que vous puissiez construire une regex qui fasse exactement ce que vous voulez, mais cela devrait être assez proche (j'espère).

Edit 3: New regex - doit gérer plusieurs déclarations

Regex t = new Regex(@"when\s+(.*?)\s+then\s+(.*?)(?=(when|end))", RegexOptions.Singleline) 

Il contient une positive afin que préanalyse le deuxième groupe correspond de puis à l'autre 'quand' 'fin' ou. Dans mon test, il a travaillé avec ceci:

case a 
when cond1 
then stmt1; 
    stm1; 
    stm2;stm3 
when cond2 
then stmt2; 
    aaa; 
    bbb; 
end case; 

Il est sensible à la casse pour l'instant, donc si vous avez besoin la casse vous devez ajouter le drapeau correspondant regex.

+0

oui, c'est vrai, mais pour cela je peux vérifier la prochaine occurrence de cas et retirer la chaîne avant d'appliquer un motif sur elle et peut obtenir toutes les correspondances possibles. Alors, pouvez-vous s'il vous plaît aider à former la regex? – Archie

+0

Eh bien, j'ai essayé cette regex, mais cela ne fonctionne pas. également, selon l'expression de cas dans pl/sql, il peut y avoir plusieurs instructions après. – Archie

+0

Edit 3 a abouti à deux matches avec trois groupements (cond1 stmt1; when) dans chaque match. – Will

0

Si cela a été écrit en Java, j'écrirais deux modèles pour l'analyseur, l'un pour faire correspondre les cas et l'autre pour correspondre aux cas où-alors.Voici comment ce dernier pourrait être écrit:

CharSequence buffer = inputString.subSequence(0, inputString.length()); 
// inputString is the string you get after matching the case statements... 

Pattern pattern = Pattern.compile(
    "when (\\S+).*" 
    + "then (\\S+).*"); 

Matcher matcher = pattern.matcher(buffer); 
while (matcher.find()) { 
    DoWhenThen(matcher.group(1), matcher.group(2)); 
} 

Note: Je ne l'ai pas testé ce code comme je ne suis pas sûr à 100% sur le modèle ... mais je serais bricoler ça.

+0

merci beaucoup, mais je dois l'implémenter en C#. – Archie

1

Je ne pense pas que ce soit possible, principalement parce que tout groupe qui correspond quand ... alors ... va tous les faire correspondre, créant plusieurs captures dans le même groupe.

Je suggère d'utiliser cette regex:

(?:when(.*)\nthen(.*)\n)+? 

qui se traduit par:

Match 1:
* Groupe 1: cond1
* Groupe 2: stmt1;
Correspondance 2:
* Groupe 1: cond2
* Groupe 2: stmt2;

+0

Merci beaucoup. mais cette regex ne fonctionne qu'avec quand sur newline. Donc essayé de le modifier comme (?: Lorsque (. *) \ S + alors (. *) \ S *) +? mais ça ne marche toujours pas. – Archie

+0

Hmm, j'ai copié votre exemple de texte et testé contre cela. Peut-être que vos données réelles sont différentes? Je n'ai aucun ensemble d'options regex (pas SingleLine, pas MultiLine). Est-ce que 'quand' ne démarre pas sur une nouvelle ligne? – Will

+0

pas nécessairement. Je ne pense pas qu'il donne une erreur de syntaxe si "quand" ne démarre pas sur newline. – Archie

Questions connexes