2010-10-01 11 views
6

Come posso utilizzare il lookbehind in un C# Regex per saltare le corrispondenze di ripetizioni di prefissi?Come posso utilizzare lookbehind in un C# Regex per saltare le corrispondenze di ripetizioni di prefissi?

Esempio - Sto cercando di avere la partita espressione tutti i b caratteri che seguono un qualsiasi numero di caratteri a:

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

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

rendimenti aabbbb, l'lookbehind corrispondenza solo a. Come posso fare in modo che corrisponda a tutti gli a s all'inizio?

Ho provato

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

e

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

senza risultati ...

Quello che mi aspetto è bbbb.

+0

Qual è il tuo risultato previsto? – splash

risposta

6

Siete alla ricerca di un gruppo catturato ripetutamente?

(.)\1* 

Questo restituirà due corrispondenze.

Dato:

aaabbbb 

Questo si tradurrà in:

aaa 
bbbb 

questo:

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

Utilizza il capitale di cui sopra, dopo aver verificato che la constatazione del carattere precedente, catturarlo in un riferimento posteriore, e quindi affermando che quel personaggio non è il prossimo personaggio.

che corrisponde:

bbbb 
+0

Ho bisogno del gruppo lookbehind per abbinare tutti i caratteri. Cioè, la corrispondenza effettiva è bbbb, poiché il gruppo di ripetuti a dovrebbe essere ignorato. – luvieere

+0

@luvieere: ho apportato questa modifica. –

1

Il motivo per cui il look-behind sta saltando la "a" è perché consuma la prima "a" (ma non la cattura), quindi cattura il resto.

Questo modello potrebbe funzionare al posto tuo? Nuovo modello: \ba+(.+)\b Utilizza un limite di parola \b per ancorare entrambe le estremità della parola. Corrisponde ad almeno una "a" seguita dal resto dei caratteri fino alla fine del confine della parola. I restanti personaggi vengono catturati in un gruppo in modo da poterli fare facilmente riferimento.

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: Se si desidera saltare la prima occorrenza di eventuali lettere duplicati, quindi abbinare il resto della stringa, si potrebbe fare questo:

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

Fallo senza avere "b" o "a" nella tua espressione regolare. –

+0

@John grazie Sono stato fissato sulla lettera "a" nello specifico. Il mio secondo esempio funziona con qualsiasi carattere duplicato e senza hardcoding. –

+0

OK, +1, direi che il mio è un po 'più conciso, ma sembra che sia più facile da leggere. –

3

ho capito alla fine:

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

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

non deve permettere l'a s per me corrispondente al gruppo non-lookbehind. In questo modo, l'espressione corrisponderà solo alle ripetizioni b che seguono le ripetizioni a.

corrispondenza aaabbbb rendimenti bbbb e la congruenza aaabbbbcccbbbbaaaaaabbzzabbb risultati in bbbbcccbbbb, bbzz e bbb.