2010-10-01 8 views
6

Wie kann ich Lookbehind in einem C# Regex verwenden, um Übereinstimmungen wiederholter Präfixmuster zu überspringen?Wie kann ich Lookbehind in einem C# Regex verwenden, um Übereinstimmungen wiederholter Präfixmuster zu überspringen?

Beispiel - Ich versuche, den Ausdruck durch alle b Zeichen von a Zeichen nach einer beliebigen Anzahl zu haben:

Regex expression = new Regex("(?<=a).*"); 

foreach (Match result in expression.Matches("aaabbbb")) 
    MessageBox.Show(result.Value); 

kehrt aabbbb, passend zu den Lookbehind nur ein a. Wie kann ich es so machen, dass es am Anfang alle a s entspricht?

Ich habe versucht,

Regex expression = new Regex("(?<=a+).*"); 

und

Regex expression = new Regex("(?<=a)+.*"); 

ohne Ergebnisse ...

Was ich erwarte bbbb ist.

+0

Was ist Ihr Ergebnis? – splash

Antwort

6

Sie sind auf der Suche nach eine wiederholte einfangende Gruppe?

(.)\1* 

Dadurch werden zwei Übereinstimmungen zurückgegeben.

Gegeben:

aaabbbb 

Dies wird zur Folge haben:

aaa 
bbbb 

Dieses:

(?<=(.))(?!\1).* 

die obige Haupteinsatz zunächst prüfen, ob die das vorherige Zeichen zu finden, ist es die Erfassung in eine Rückreferenz und dann bestätigen, dass dieses Zeichen nicht das nächste Zeichen ist.

Das passt:

Regex expression = new Regex("(?<=a+)[^a]+"); 

foreach (Match result in expression.Matches(@"aaabbbb")) 
    MessageBox.Show(result.Value); 

ich erlauben darf die a s mir durch die Nicht-Lookbehind Gruppe abgestimmt:

bbbb 
+0

Ich brauche die Lookbehind-Gruppe, um alle a-Zeichen zu finden. Das heißt, die tatsächliche Übereinstimmung ist bbbb, da die Gruppe von wiederholtem a ignoriert werden sollte. – luvieere

+0

@luvieere: Ich habe diese Änderung vorgenommen. –

1

Der Grund, warum der Lookback das "a" überspringt, ist, weil er das erste "a" verbraucht (aber nicht erfasst), dann fängt es den Rest ein.

Würde dieses Muster stattdessen für Sie arbeiten? Neues Muster: \ba+(.+)\b Es verwendet eine Wortgrenze \b, um beide Enden des Wortes zu verankern. Es passt mindestens ein "a" an, gefolgt von den restlichen Zeichen, bis die Wortgrenze endet. Die verbleibenden Zeichen werden in einer Gruppe erfasst, sodass Sie sie leicht referenzieren können.

string pattern = @"\ba+(.+)\b"; 

foreach (Match m in Regex.Matches("aaabbbb", pattern)) 
{ 
    Console.WriteLine("Match: " + m.Value); 
    Console.WriteLine("Group capture: " + m.Groups[1].Value); 
} 

UPDATE: Wenn Sie das erste Vorkommen von beliebigen dupliziert Buchstaben überspringen wollen, dann den Rest der Zeichenfolge übereinstimmen, können Sie dies tun:

string pattern = @"\b(.)(\1)*(?<Content>.+)\b"; 

foreach (Match m in Regex.Matches("aaabbbb", pattern)) 
{ 
    Console.WriteLine("Match: " + m.Value); 
    Console.WriteLine("Group capture: " + m.Groups["Content"].Value); 
} 
+0

Tun Sie es, ohne 'b' oder 'a' in Ihrer Regex zu haben. –

+0

@John danke Ich war speziell auf den Buchstaben "a" fixiert. Mein zweites Beispiel funktioniert mit jedem duplizierten Zeichen und ohne es hart zu codieren. –

+0

In Ordnung, +1, ich würde argumentieren, dass meine etwas knapper ist, aber es sieht so aus, als ob das einfacher zu lesen ist. –

3

ich es schließlich herausgefunden. Auf diese Weise stimmt der Ausdruck nur mit den b Wiederholungen überein, die auf a Wiederholungen folgen.

Passende aaabbbbbbbb Ausbeuten und passende Ergebnisse in aaabbbbcccbbbbaaaaaabbzzabbbbbbbcccbbbb, bbzz und bbb.