2010-02-12 7 views
6

Estoy haciendo una pequeña aplicación usando tipos .NET Regex. Y los tipos "Capturar, Agrupar y Coincidir" me confundieron por completo. Nunca he visto una solución tan fea. ¿Podría alguien explicarme su uso? Muchas gracias.Diferencias entre .NET Capture, Group, Match

+0

¿Tiene un ejemplo de expresión regular que quiere que lo expliquemos? – Gumbo

Respuesta

12

Aquí está un ejemplo simple que el uno en el documento @Dav citados:

string s0 = @"foo%123%456%789"; 
Regex r0 = new Regex(@"^([a-z]+)(?:%([0-9]+))+$"); 
Match m0 = r0.Match(s0); 
if (m0.Success) 
{ 
    Console.WriteLine(@"full match: {0}", m0.Value); 
    Console.WriteLine(@"group #1: {0}", m0.Groups[1].Value); 
    Console.WriteLine(@"group #2: {0}", m0.Groups[2].Value); 
    Console.WriteLine(@"group #2 captures: {0}, {1}, {2}", 
        m0.Groups[2].Captures[0].Value, 
        m0.Groups[2].Captures[1].Value, 
        m0.Groups[2].Captures[2].Value); 
} 

resultado:

full match: foo%123%456%789
group #1: foo
group #2: 789
group #2 captures: 123, 456, 789

Los resultados full match y group #1 son sencillos, pero los otros requieren alguna explicación. El Grupo # 2, como puede ver, está dentro de un grupo que no captura y que está controlado por un cuantificador +. Coincide tres veces, pero si solicita su Value, solo obtendrá lo que coincide la tercera vez: la captura final. Del mismo modo, si usa el marcador de posición $2 en una cadena de reemplazo, la captura final es lo que se inserta en su lugar.

En la mayoría de los sabores de regex, eso es todo lo que puede obtener; cada captura intermedia se sobrescribe con la siguiente y se pierde; .NET es casi único al conservar todas las capturas y ponerlas a disposición después de que se realice la coincidencia. Puede acceder a ellos directamente como lo hice aquí, o recorrer el CaptureCollection como lo haría con un MatchCollection. Sin embargo, no existe un equivalente para los marcadores de posición de cadena de reemplazo de estilo $1.

Por lo tanto, el motivo por el cual el diseño de la API es tan feo (como usted dice) es doble: primero fue adaptado del soporte de expresiones regulares integrales de Perl al marco orientado a objetos de .NET; luego se injertó la estructura CaptureCollection. Perl 6 ofrece una solución mucho más limpia, pero los autores lo lograron reescribiendo Perl prácticamente desde cero y lanzando hacia atrás compatibilidad hacia atrás.

+1

Hola, gracias Alan. Tan solo 2 preguntas más, hay una propiedad llamada "Capturas" para Match y Group, ¿cuál es la diferencia entre Match.Captures y Group.Captures? ¿Y por qué el Match.Groups [0] es siempre el mismo que el Match.Value? Gracias de nuevo. – smwikipedia

+0

Igualar la captura de ISA Group ISA, por lo que Match hereda 'Captures' from Group y' Value' de Capture. The Match es el Grupo cero, por lo que 'Match.Captures' es simplemente una lista de un elemento que contiene la coincidencia completa, ¡como si necesitáramos * otra * forma de referirnos a ella! 'Value' es obviamente la forma preferida, siendo mucho más corto e intuitivo. Pero incluso eso es opcional si usa la referencia Match/Group/Capture que espera una cadena, porque 'ToString()' simplemente delega en 'Value'. –

+0

En cuanto a * por qué * el partido es el grupo número cero, mira esta respuesta: http://stackoverflow.com/questions/2248213/in-c-expresion-regular-que-hace-el-entramiento-inicial) -up-in-the-groups/2248767 # 2248767 –

2

Una coincidencia es el resultado de cualquier coincidencia individual de entera de una expresión regular. Los grupos y las capturas tienen algo que ver con los grupos de captura (cada (expression) desde dentro de la expresión regular), pero varían en la forma en que se comportan. He aquí una cita del artículo de MSDN en la clase de captura que explica la diferencia:

Si no se aplican un cuantificador a un grupo captura, los Group.Captures propiedad devuelve un CaptureCollection con un único objeto de captura que proporciona información sobre la misma captura que el objeto Grupo. Si aplicar un cuantificador a un grupo captura, el Group.Index, Group.Length, y propiedades Group.Value proporcionar información únicamente sobre el último grupo capturado , mientras que la captura de objetos en el CaptureCollection proporcionar información sobre todas las capturas de subexpresiones . El ejemplo proporciona una ilustración.

(Source)

Cuestiones relacionadas