Wprowadzenie
Dzisiaj zagłębimy się w temat, który często budzi respekt wśród programistów, ale jest niezwykle potężnym narzędziem w pracy z tekstem. Wyrażenia regularne (regex) pozwalają na zaawansowane wyszukiwanie, walidację i manipulację danymi tekstowymi. W tym artykule skupimy się na praktycznym zastosowaniu regex w C# i .NET.
Co to są wyrażenia regularne?
Wyrażenia regularne to sekwencje znaków definiujące wzorzec wyszukiwania. Pozwalają na:
• Wyszukiwanie określonych ciągów znaków
• Walidację formatu danych (np. email, numer telefonu)
• Ekstrakcję informacji z tekstu
• Zaawansowaną manipulację stringami
Podstawowe elementy wyrażeń regularnych
Zanim przejdziemy do przykładów, poznajmy kilka podstawowych elementów:
• . - dowolny znak
• * - zero lub więcej wystąpień
• + - jedno lub więcej wystąpień
• ? - zero lub jedno wystąpienie
• ^ - początek linii
• $ - koniec linii
• [] - zestaw znaków
• [^] - negacja zestawu znaków
• \d - cyfra
• \w - znak alfanumeryczny
• \s - biały znak
Przykłady użycia regex w C#
1. Wyszukiwanie wzorca
Zacznijmy od prostego przykładu - wyszukiwania adresów email:
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string text = "Kontakt: jan@example.com, anna@firma.pl";
string pattern = @"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b";
MatchCollection matches = Regex.Matches(text, pattern);
foreach (Match match in matches)
{
Console.WriteLine($"Znaleziono email: {match.Value}");
}
}
}
2. Walidacja danych
Sprawdźmy, czy podany ciąg znaków jest poprawnym kodem pocztowym:
static bool IsValidPostalCode(string postalCode)
{
string pattern = @"^\d{2}-\d{3}$";
return Regex.IsMatch(postalCode, pattern);
}
/* Użycie: */
Console.WriteLine(IsValidPostalCode("12-345")); /* True */
Console.WriteLine(IsValidPostalCode("1-23")); /* False */
3. Ekstrakcja informacji
Wyodrębnianie numerów telefonów z tekstu:
string text = "Zadzwoń do Jana: 123-456-789 lub do Anny: 987-654-321";
string pattern = @"\d{3}-\d{3}-\d{3}";
MatchCollection matches = Regex.Matches(text, pattern);
foreach (Match match in matches)
{
Console.WriteLine($"Znaleziono numer: {match.Value}");
}
4. Zamiana tekstu
Zamiana formatu daty:
string text = "Data urodzenia: 1990-05-15";
string pattern = @"(\d{4})-(\d{2})-(\d{2})";
string replacement = "$3.$2.$1";
string result = Regex.Replace(text, pattern, replacement);
Console.WriteLine(result); /* Data urodzenia: 15.05.1990 */
5. Grupowanie i przechwytywanie
Analiza logów:
string log = "2023-05-10 14:30:45 ERROR: Błąd połączenia z bazą danych";
string pattern = @"(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2}) (\w+): (.+)";
Match match = Regex.Match(log, pattern);
if (match.Success)
{
Console.WriteLine($"Data: {match.Groups[1].Value}");
Console.WriteLine($"Czas: {match.Groups[2].Value}");
Console.WriteLine($"Poziom: {match.Groups[3].Value}");
Console.WriteLine($"Wiadomość: {match.Groups[4].Value}");
}
Zaawansowane techniki
Lookahead i Lookbehind
Te techniki pozwalają na bardziej złożone wyszukiwanie:
/* Pozytywny lookahead */
string pattern = @"\b\w+(?=ing\b)";
string text = "I am running and jumping";
MatchCollection matches = Regex.Matches(text, pattern);
foreach (Match match in matches)
{
Console.WriteLine(match.Value); /* Wypisze: "runn", "jump" */
}
/* Negatywny lookbehind */
pattern = @"(?<!un)\w+ing\b";
matches = Regex.Matches(text, pattern);
foreach (Match match in matches)
{
Console.WriteLine(match.Value); /* Wypisze: "jumping" */
}
Nazwane grupy
Ułatwiają pracę z złożonymi wyrażeniami:
string pattern = @"(?<date>\d{4}-\d{2}-\d{2}) (?<time>\d{2}:\d{2}:\d{2}) (?<level>\w+): (?<message>.+)";
Match match = Regex.Match(log, pattern);
if (match.Success)
{
Console.WriteLine($"Data: {match.Groups["date"].Value}");
Console.WriteLine($"Czas: {match.Groups["time"].Value}");
Console.WriteLine($"Poziom: {match.Groups["level"].Value}");
Console.WriteLine($"Wiadomość: {match.Groups["message"].Value}");
}
Dobre praktyki
1. Testuj swoje wyrażenia regularne na różnych przypadkach.
2. Używaj komentarzy w złożonych wyrażeniach ((?#komentarz)).
3. Unikaj nadmiernego używania regex dla prostych operacji na stringach.
4. Kompiluj wyrażenia regularne dla lepszej wydajności przy wielokrotnym użyciu.
Podsumowanie
Wyrażenia regularne to potężne narzędzie w arsenale każdego programisty .NET. Pozwalają na efektywne przetwarzanie i analizę tekstu, co jest nieocenione w wielu zastosowaniach - od walidacji danych po zaawansowane przetwarzanie języka naturalnego. Jeśli chcesz pogłębić swoją wiedzę na temat wyrażeń regularnych oraz innych zaawansowanych technik programowania w .NET, zachęcam do sprawdzenia mojego szkolenia online "Zostań Programistą .NET". W szkoleniu tym szczegółowo omawiamy nie tylko regex, ale także wiele innych kluczowych aspektów programowania, które pomogą Ci stać się skutecznym deweloperem .NET. Dziękuję za uwagę! Jeśli masz pytania lub chcesz podzielić się swoimi doświadczeniami z używaniem wyrażeń regularnych w C#, zostaw komentarz poniżej. Powodzenia w Twojej przygodzie z programowaniem!