2009-05-08 15 views
20

Diga, tengo una cadena que necesito para verificar el formato correcto de; p.ej. RR1234566-001 (2 letras, 7 dígitos, guión, 1 o más dígitos). Utilizo algo como:Expresiones regulares C# - ¿es posible extraer coincidencias durante la coincidencia?

 Regex regex = new Regex(patternString); 
     if (regex.IsMatch(stringToMatch)) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 

Esto funciona para mí decir si la stringToMatch sigue el modelo definido por patternString. Sin embargo, lo que necesito (y termino extrayendo estos más tarde) son: 123456 y 001 - es decir, porciones del stringToMatch.

Tenga en cuenta que esta NO es una pregunta acerca de cómo construir expresiones regulares. Lo que estoy preguntando es: "¿Hay alguna manera de unir y extraer valores simultáneamente sin tener que usar una función dividida más adelante?"

+0

Tenga en cuenta que sólo puede volver: 'volver regex.IsMatch (...) // código de la question' o ' volver match.Success // código de los aceptados disoluciones para retornos en if/else no son necesarios :) –

Respuesta

54

Puede usar grupos regex para lograr eso. Por ejemplo, esta expresión regular:

(\d\d\d)-(\d\d\d\d\d\d\d) 

Vamos a coincidir con un número de teléfono con esta expresión regular:

var regex = new Regex(@"(\d\d\d)-(\d\d\d\d\d\d\d)"); 
var match = regex.Match("123-4567890"); 
if (match.Success) 
    .... 

Si coincide, se encuentra los tres primeros dígitos en:

match.Groups[1].Value 

Y los segundos 7 dígitos en:

match.Groups[2].Value 

P.S. En C#, puede usar una cadena de estilo @ "" para evitar el escape de las barras diagonales inversas. Por ejemplo, @ "\ hi \" es igual a "\\ hi \\". Útil para expresiones y rutas regulares.

P.S.2. El primer grupo se almacena en el Grupo [1], no en el Grupo [0] como era de esperar. Eso es porque el Grupo [0] contiene la cadena completa coincidente.

+9

+1 ¡Muy completo! Sin embargo, agregaría una cosa: la razón por la que comienzas el partido. Grupos [1] y no [0] es porque [0] contiene la cadena completa. –

+0

Gracias @NeilWilliams, ¡me lo estaba preguntando! – M3NTA7

13

Utilice agrupación y coincidencias en su lugar.

Es decir:

// NOTE: pseudocode. 
Regex re = new Regex("(\\d+)-(\\d+)"); 
Match m = re.Match(stringToMatch)) 

if (m.Success) { 
    String part1 = m.Groups[1].Value; 
    String part2 = m.Groups[2].Value; 
    return true; 
} 
else { 
    return false; 
} 

También puede nombrar los partidos, como esto:

Regex re = new Regex("(?<Part1>\\d+)-(?<Part2>\\d+)"); 

y acceso como esto

String part1 = m.Groups["Part1"].Value; 
    String part2 = m.Groups["Part2"].Value; 
+0

consejo muy útil! – sarsnake

+0

+1 para grupos con nombre –

12

Se pueden utilizar paréntesis para capturar grupos de caracteres :

string test = "RR1234566-001"; 

// capture 2 letters, then 7 digits, then a hyphen, then 1 or more digits 
string rx = @"^([A-Za-z]{2})(\d{7})(\-)(\d+)$"; 

Match m = Regex.Match(test, rx, RegexOptions.IgnoreCase); 

if (m.Success) 
{ 
    Console.WriteLine(m.Groups[1].Value); // RR 
    Console.WriteLine(m.Groups[2].Value); // 1234566 
    Console.WriteLine(m.Groups[3].Value); // - 
    Console.WriteLine(m.Groups[4].Value); // 001 
    return true; 
} 
else 
{ 
    return false; 
} 
+2

+1 para la expresión regular correcta ... por cierto, si usa IgnoreCase, puede usar [a-z] en lugar de [A-Za-z]. – Andomar

-1
string text = "RR1234566-001"; 
string regex = @"^([A-Z a-z]{2})(\d{7})(\-)(\d+)"; 
Match mtch = Regex.Matches(text,regex); 
if (mtch.Success) 
{ 
    Console.WriteLine(m.Groups[1].Value);  
    Console.WriteLine(m.Groups[2].Value);  
    Console.WriteLine(m.Groups[3].Value);  
    Console.WriteLine(m.Groups[4].Value);  
    return true; 
} 
else 
{ 
    return false; 
} 
Cuestiones relacionadas