2009-03-12 10 views
1

zu bekommen Ich lerne Regex und brauche etwas Hilfe, um alle möglichen Übereinstimmungen für ein Muster aus einer Zeichenfolge zu erhalten.Regex, um alle möglichen Übereinstimmungen für ein Muster in C#

Wenn mein Eingang ist:

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

Ich brauche die Spiele zu bekommen, die Gruppen wie folgt

Gruppe1:

  1. "cond1"
  2. "stmt1;"

und Group2:

  1. "cond2"
  2. "stmt2;"

Ist es möglich, solche Gruppen zu bekommen jede Regex?

+0

Ich glaube nicht, dass ich verstehe. Was hat dein Code mit Regexes zu tun? – Grzenio

+0

ich dachte, es wäre einfacher, alle solche Schleifen/Blöcke mit Regex zu bekommen, anstatt sie durch traditionelle Programmierung Weg zu verarbeiten.Auch kann ich solche Regex verwenden, um viele solcher unterschiedlichen Strukturen zu analysieren. – Archie

+0

Ich denke, Sie sollten einen Parser schreiben, Parsing Quellcode mit regulären Ausdrücken allein wird nicht funktionieren. – Tomalak

Antwort

6

Es ist möglich, Regex zu verwenden, vorausgesetzt, Sie verschachteln Ihre Anweisungen nicht. Zum Beispiel, wenn Ihre Stmt1 eine andere Case-Anweisung ist, dann sind alle Wetten aus (Sie können Regex für so etwas nicht verwenden, Sie brauchen einen regulären Parser).

bearbeiten: Wenn Sie es wirklich wollen, um versuchen Sie es mit so etwas wie tun kann (nicht getestet, aber Sie bekommen die Idee):

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

Aber wie ich das gesagt wird nur für nicht funktionieren verschachtelte Anweisungen.

Bearbeiten 2: Ein wenig die Regex geändert, um das Semikolon in der letzten Gruppe aufzunehmen. Dies wird nicht funktionieren, wie Sie wollten - stattdessen gibt es Ihnen mehrere Übereinstimmungen und jede Übereinstimmung wird eine darstellen, wenn Bedingung, mit der ersten Gruppe die Bedingung und die zweite Gruppe die Aussage.

Ich glaube nicht, dass Sie eine Regex bauen können, die genau das tut, was Sie wollen, aber das sollte nahe genug sein (ich hoffe).

bearbeiten 3: New Regex - sollten mehrere Anweisungen

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

Es enthält eine positive Vorschauhandhaben, so dass die zweite Gruppe von übereinstimmt dann auf die nächste 'wenn' oder 'Ende'. In meinem Test funktionierte es dies mit:

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

Es ist Groß- und Kleinschreibung für jetzt, wenn Sie also Groß- und Kleinschreibung müssen müssen Sie den entsprechenden regex Flag hinzuzufügen.

+0

Ja, das ist richtig, aber dafür kann ich nach dem nächsten Fall suchen und die Zeichenfolge entfernen, bevor ich ein Muster darauf anlege und alle möglichen Übereinstimmungen bekommen kann. Also, können Sie bitte helfen, die Regex zu bilden? – Archie

+0

Nun, ich habe diesen Regex versucht, aber es funktioniert nicht. auch, nach dem Fall Ausdruck in pl/SQL gibt es mehrere Aussagen nach dann. – Archie

+0

Edit 3 führte zu zwei Übereinstimmungen mit drei Gruppierungen (cond1 stmt1; when) in jedem Spiel. – Will

0

Wenn dies in Java geschrieben wurde, würde ich zwei Muster für den Parser schreiben, einen, um die Fälle zu vergleichen, und einen, um die Wenn-dann-Fälle zu entsprechen.Hier ist, wie diese geschrieben werden könnte:

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)); 
} 

Hinweis: Ich kann nicht diesen Code getestet haben, da ich nicht 100% sicher auf dem Muster bin ... aber ich würde dies zu umgehen werden bastelt.

+0

vielen Dank, aber ich muss es in C# implementieren. – Archie

1

Ich denke nicht, dass dies möglich ist, vor allem, weil jede Gruppe, die übereinstimmt, wenn ... dann ... wird alle übereinstimmen, mehrere Aufnahmen innerhalb der gleichen Gruppe erstellen.

Ich würde vorschlagen, diese Regex:

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

die Ergebnisse:

Match 1:
* Gruppe 1: cond1
* Gruppe 2: stmt1;
Übereinstimmung 2:
* Gruppe 1: cond2
* Gruppe 2: stmt2;

+0

Vielen Dank. aber diese Regex funktioniert nur mit newline. Also versucht, es als (?: Wenn (. *) \ S + dann (. *) \ S *) +? aber es funktioniert immer noch nicht. – Archie

+0

Hmm, ich habe deinen Beispieltext kopiert und dagegen getestet. Vielleicht sind deine tatsächlichen Daten anders? Ich habe keine Regex-Optionen (keine SingleLine, keine MultiLine). Nicht "wenn" auf einer neuen Zeile beginnen? – Will

+0

nicht unbedingt. Ich denke nicht, dass es einen Syntaxfehler gibt, wenn "Wenn" nicht auf Newline beginnt. – Archie

Verwandte Themen