2009-05-08 6 views
20

Powiedzmy, mam ciąg znaków, który muszę zweryfikować poprawny format; na przykład RR1234566-001 (2 litery, 7 cyfr, myślnik, 1 lub więcej cyfr). Używam coś takiego:Wyrażenia regularne C# - czy można wyodrębnić dopasowania podczas dopasowywania?

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

to działa mi powiedzieć, czy stringToMatch następujący wzór określony przez patternString. To, czego potrzebuję (i kończę wydobywając je później) to: 123456 i 001 - tj. Części stringToMatch.

Należy pamiętać, że NIE jest to kwestia sposobu konstruowania wyrażeń regularnych. Pytam: "Czy istnieje sposób, aby dopasować i wyodrębnić wartości jednocześnie bez konieczności korzystania z funkcji podziału później?"

+0

pamiętać, że można po prostu wrócić: 'powrócić regex.IsMatch (...) // kod z question' lub ' powrócić match.Success // kod z przyjętymi solution' zwrotów in/if/else were not needed :) –

Odpowiedz

54

Możesz użyć grup regex, aby to osiągnąć. Na przykład, wyrażenie regularne:

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

Niech meczu numer telefonu z tym regex:

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

Jeśli pasuje, będzie znaleźć pierwsze trzy cyfry w:

match.Groups[1].Value 

I drugie 7 cyfr:

match.Groups[2].Value 

P.S. W języku C# można użyć ciągu znaków w stylu @ "", aby uniknąć ucieczki ukośników odwrotnych. Na przykład @ "\ hi \" jest równy "\\ hi \\". Przydatny w przypadku wyrażeń regularnych i ścieżek.

P.S.2. Pierwsza grupa jest przechowywana w grupie [1], a nie w grupie [0], jak można się spodziewać. Dzieje się tak, ponieważ grupa [0] zawiera cały dopasowany ciąg.

+9

+1 Bardzo dokładny! Dodałbym jednak jedną rzecz, powód, dla którego zaczynasz na match.Groups [1], a nie [0], ponieważ [0] zawiera cały dopasowany ciąg. –

+0

Dzięki @NeilWilliams, zastanawiałem się, że! – M3NTA7

13

Zamiast tego użyj grupowania i dopasowań.

Ie:

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

Można również wymienić mecze, jak ten:

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

i dostęp jak ten

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

bardzo przydatna wskazówka! – sarsnake

+0

+1 dla nazwanych grup –

12

Można użyć nawiasów aby uchwycić grup znaków :

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 dla prawego regex ... btw jeśli używasz IgnoreCase, możesz użyć [a-z] zamiast [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; 
}