2009-12-01 20 views
5

Esta es mi primera experiencia con C# y parte de mi experiencia limitada con expresiones regulares y tengo problemas para capturar la primera aparición de una coincidencia en una expresión en particular. Creo que el siguiente ejemplo lo dejaría más claro que las palabras al describir lo que quiero hacer.Captura de la primera coincidencia con expresiones regulares (C#)

Match extractor = (new Regex(@".*\d(?<name>.*)\d.*")).Match("This hopefully will pick up 1Bob9error1 as a name"); 
     Console.WriteLine(extractor.Groups["name"]); 

Me gustaría esta expresión para imprimir "Bob" en lugar de "error".

Tengo la corazonada de que tiene algo que ver con el? frente al grupo coincidente, pero no estoy exactamente seguro de qué operación es? realiza en este caso particular. Una explicación junto con algo de ayuda sería maravillosa.

Gracias chicos, no tienen idea de cuánto ayuda este sitio a un programador principiante como yo.

+0

(? yourRegEx) significa un grupo capturado que puede tener el nombre "nombre". Esta es la razón por la que puede usar extractor.Grupos ["nombre"] – nickytonline

Respuesta

7

Su problema es la codicia. La avaricia Regex que es. Tu. * Al principio toma todo esto "Espero que recoja 1Bob". intente este Regex en su lugar:

\d(?<name>[^\d]+)\d 
+0

Chad, le recomiendo que instale RegExWorkbench, http://code.msdn.microsoft.com/RegexWorkbench. Es un proyecto viejo pero impresionante hecho por Eric Gunnerson. Si no tiene instalado .NET 1.x framework, proporciona el origen para que pueda compilarlo utilizando el marco que ha instalado. – nickytonline

+0

Que realmente recogió "Bob". Increíble. Creo que mi problema fue que traté esta expresión regular como si tuviera que coincidir con toda la cadena, cuando realmente solo estaba preguntando si había una coincidencia. Gracias un montón – Chad

+0

Tienes que recordar que con expresiones regulares,. y * puede ser muy malvado. Cuando crea su expresión regular, realmente necesita saber lo que quiere encontrar y solo eso. Lleva tiempo, pero una vez que lo haga de manera consistente, terminará con expresiones regulares sólidas. También recomiendo este sitio, http://www.regular-expressions.info y que lea este libro, Mastering Regular Expressions, http://regex.info. – nickytonline

3

Coincide con el elemento anterior cero o una vez. Es equivalente a {0,1}. ? es un cuantificador codicioso cuyo equivalente no codicioso es ??.

Tomado de here. El sitio incluye una hoja de trucos para expresiones regulares, y al mirar tu expresión, parece que no puedo descubrir qué puede haber mal con ella.

Mi hipótesis es que podría coincidir con la última aparición de su expresión.

+0

Podría estar equivocado, pero no creo que el? es un cuantificador en este caso. ¿Los cuantificadores usualmente no siguen una expresión? – Chad

+0

No hay nada de malo con la expresión, solo está mirando el segundo valor que está capturando en lugar del primero. – Rory

+0

@Chad The? en este contexto, indica el inicio de un grupo nombrado (más específicamente el que se llama "nombre"). En la mayoría de los otros lugares se usa como un cuantificador. – Rory

2

Cada elemento Grupo tiene una colección captura, puede acceder a la primera captura de un grupo usando:

extractor.Groups["name"].Captures[0] 
+0

P.S. Cada elemento de captura tiene una propiedad de valor que devuelve el valor de cadena real de la captura, también hay otras propiedades útiles, como el índice en el que se inicia la captura en la cadena original y la longitud de la captura. En caso de duda, presione F1. – Rory

+0

Hmmmm ... información útil, pero Captures [0] aún detecta el "error" ¿Hay algún error en mi expresión regular? – Chad

2

Los caracteres de * horquillado alrededor de su expresión están causando el problema. Recuerde que no necesita una expresión regular que coincida con la cadena completa ; desea que coincida solo con un patrón en particular cuando aparezca. El siguiente código funciona:

Regex pattern = new Regex(@"\d(?<name>.*?)\d"); 
MatchCollection matches = pattern.Matches("This hopefully will pick up 1Bob9error1 as a name"); 
Console.WriteLine(matches[0].Groups["name"]); 
Cuestiones relacionadas