2010-10-01 8 views
6

Jak mogę użyć lookbehind w C# Regex, aby pominąć dopasowania powtarzających się wzorców prefiksów?Jak mogę użyć lookbehind w C# Regex, aby pominąć dopasowania powtarzających się wzorców prefiksów?

Przykład - Staram się mieć Dopasowanie wyrażenia wszystkie b znaki następujące dowolnej liczby a znaków:

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

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

powraca aabbbb The lookbehind dopasowanie tylko a. Jak mogę to zrobić, aby pasowało do wszystkich a s na początku?

Próbowałem

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

i

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

bez rezultatu ...

Co Czekam jest bbbb.

+0

Jaki jest twój wynik? – splash

Odpowiedz

6

Szukasz powtórzona grupa przechwytująca?

(.)\1* 

Spowoduje to wyświetlenie dwóch dopasowań.

Dane:

aaabbbb 

To spowoduje:

aaa 
bbbb 

to:

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

Używa powyższy kapitał, uprzedniego sprawdzenia, że ​​znalezienie poprzedni znak, zdobywając go w back reference, a następnie potwierdzając, że ta postać nie jest kolejną postacią.

który pasuje:

bbbb 
+0

Potrzebuję grupy lookbehind, aby dopasować wszystkie znaki. Oznacza to, że faktycznym dopasowaniem jest bbbb, ponieważ grupa powtórzeń a powinna zostać zignorowana. – luvieere

+0

@luvieere: Dokonałem tej zmiany. –

1

Powodem, dla którego nie można pominąć "a", jest pochłanianie pierwszego "a" (ale nie przechwytywanie go), a następnie przechwytuje resztę.

Czy ten wzór będzie działał dla Ciebie? Nowy wzór: \ba+(.+)\b Używa granicy słowa \b do zakotwiczenia obu końców słowa. Dopasowuje co najmniej jedno "a", a następnie pozostałe znaki, aż granica słowa się skończy. Pozostałe postacie są przechwytywane w grupie, dzięki czemu możesz łatwo się do nich odwoływać.

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: Jeśli chcesz pominąć pierwsze wystąpienie jakichkolwiek powielonych listów, a następnie dopasować resztę łańcucha, można to zrobić:

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

Zrób to bez "b" lub "a" w swoim wyrobie regularnym. –

+0

@John dziękuję Byłem ustalony na literę "a" specjalnie. Moja druga próbka działa z każdym zduplikowanym znakiem i bez jego kodowania. –

+0

W porządku, +1, twierdziłbym, że moje jest trochę bardziej zwięzłe, ale wygląda na to, że jest to łatwiejsze do odczytania. –

3

I zorientowaliśmy się ostatecznie:

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

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

nie musi umożliwić a S do mnie dopasowane przez non-lookbehind grupy. W ten sposób wyrażenie będzie pasowało tylko do powtórzeń b, które następują po powtórzeniach a.

Dopasowane aaabbbb wydajności bbbb i dopasowanie aaabbbbcccbbbbaaaaaabbzzabbb skutkuje bbbbcccbbbb, bbzz i bbb.

Powiązane problemy