2010-10-01 21 views
6

¿Cómo puedo usar lookbehind en C# Regex para omitir coincidencias de patrones de prefijos repetidos?¿Cómo puedo usar lookbehind en un C# Regex para omitir coincidencias de patrones de prefijos repetidos?

Ejemplo - Estoy tratando de tener la coincidencia de expresión de todos los caracteres siguientes b cualquier número de caracteres a:

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

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

vuelve aabbbb, la búsqueda hacia atrás a juego sólo a. ¿Cómo puedo hacer para que coincida con todos los a s al principio?

He intentado

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

y

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

sin resultados ...

Lo que estoy esperando es bbbb.

+0

¿Cuál es su resultado expirado? – splash

Respuesta

6

¿Está buscando un grupo de captura repetida?

(.)\1* 

Esto devolverá dos coincidencias.

dado:

aaabbbb 

Esto dará como resultado:

aaa 
bbbb 

Este:

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

Usos del director anterior, en primer lugar comprobar que el encontrar el carácter anterior, capturándolo en una referencia posterior, y luego afirmando que ese personaje no es el siguiente personaje.

que coincide:

bbbb 
+0

Necesito el grupo lookbehind para unir todos los caracteres a. Es decir, la coincidencia real es bbbb, ya que el grupo de repetidas a debe ignorarse. – luvieere

+0

@luvieere: He hecho ese cambio. –

1

La razón por la que el look-behind omite la "a" es porque consume la primera "a" (pero no la captura), entonces captura el resto.

¿Este patrón funcionaría para usted? Nuevo patrón: \ba+(.+)\b Utiliza un límite de palabras \b para anclar los extremos de la palabra. Coincide con al menos una "a" seguida por el resto de los caracteres hasta que la palabra límite termina. Los caracteres restantes se capturan en un grupo para que pueda referenciarlos fácilmente.

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

ACTUALIZACIÓN: Si desea omitir la primera aparición de cualquier cartas duplicadas, a continuación, que coincida con el resto de la cadena, se puede hacer esto:

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

Hazlo sin tener 'b' o 'a' en tu expresión regular. –

+0

@John gracias, estaba obsesionada con la letra "a" específicamente. Mi segunda muestra funciona con cualquier carácter duplicado y sin hardcoding. –

+0

Muy bien, +1, yo diría que el mío es un poco más conciso, pero parece que es más fácil de leer. –

3

lo he descubierto con el tiempo:

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

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

no deben permitir que los a s a mí coincidentes por el grupo sin fines de búsqueda hacia atrás. De esta forma, la expresión solo coincidirá con las repeticiones b que siguen a a repeticiones.

a juego aaabbbb rendimientos bbbb y emparejando aaabbbbcccbbbbaaaaaabbzzabbb resultados en bbbbcccbbbb, bbzz y bbb.

Cuestiones relacionadas