2010-10-01 14 views
6

Comment puis-je utiliser lookbehind dans un Regex C# afin d'ignorer les correspondances de modèles de préfixes répétés?Comment puis-je utiliser lookbehind dans une regex C# afin d'ignorer les correspondances de modèles de préfixes répétés?

Exemple - Je suis en train d'avoir le match d'expression tous les caractères suivants b un certain nombre de caractères a:

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

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

retours aabbbb, le correspondant lookbehind seulement une a. Comment puis-je faire en sorte qu'il corresponde à tous les a s au début?

J'ai essayé

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

et

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

sans résultats ...

Ce que je me attends est bbbb.

+0

Quel est votre résultat expté? – splash

Répondre

6

Vous cherchez un groupe de capture répété?

(.)\1* 

Cela retournera deux correspondances.

Étant donné:

aaabbbb 

Cela se traduira par:

aaa 
bbbb 

Ce:

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

utilise le principe ci-dessus, d'abord vérifier que la recherche du caractère précédent, capturant dans une référence arrière, puis affirmant que ce caractère n'est pas le caractère suivant.

qui correspond à:

bbbb 
+0

J'ai besoin du groupe lookbehind pour faire correspondre tous les caractères. C'est-à-dire que la correspondance réelle est bbbb, car le groupe de répété a doit être ignoré. – luvieere

+0

@luvieere: J'ai fait ce changement. –

1

La raison pour laquelle le look-behind saute le "a" est parce qu'il consomme le premier "a" (mais pas de le capturer), puis il capture le reste.

Ce modèle fonctionnerait-il pour vous? Nouveau modèle: \ba+(.+)\b Il utilise une limite de mot \b pour ancrer les deux extrémités du mot. Il correspond à au moins un "a" suivi du reste des caractères jusqu'à la fin de la limite du mot. Les caractères restants sont capturés dans un groupe afin que vous puissiez les référencer facilement.

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

MISE À JOUR: Si vous voulez sauter la première occurrence de des lettres doubles correspondre le reste de la chaîne, vous pouvez le faire:

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

Faites-le sans 'b' ou 'a' dans votre regex. –

+0

@John merci j'ai été fixé sur la lettre "a" spécifiquement. Mon deuxième exemple fonctionne avec n'importe quel caractère dupliqué et sans le coder en dur. –

+0

D'accord, +1, je dirais que le mien est un peu plus concis, mais il semble que ce soit plus facile à lire. –

3

I figured it out finalement:

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

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

je ne dois pas permettre aux a de moi abondés par le Groupe non lookbehind. De cette façon, l'expression correspondra uniquement aux répétitions b qui suivent a répétitions.

correspondants aaabbbb rendements bbbb et correspondant à aaabbbbcccbbbbaaaaaabbzzabbb résultats dans bbbbcccbbbb, bbzz et bbb.