Регулярные выражения в C#: полное руководство для начинающих
Регулярные выражения (regular expressions, regex) — это мощный инструмент для поиска, замены и проверки строк по заданному шаблону. В C# (.NET) работа с регулярными выражениями реализована через пространство имен System.Text.RegularExpressions. Эта статья поможет вам освоить основы: от создания простейших шаблонов до использования всех возможностей класса Regex.
1. Основы работы с Regex в C#
Для начала подключите пространство имен:
using System.Text.RegularExpressions;
Класс Regex предоставляет статические и экземплярные методы. Самый простой способ проверить, содержит ли строка подстроку по шаблону — метод IsMatch:
string text = "Привет, мой email: test@example.com";
string pattern = @"\w+@\w+\.\w+"; // простой шаблон email
bool hasEmail = Regex.IsMatch(text, pattern);
Console.WriteLine(hasEmail); // True
Разбор шаблона:
\w+— одна или более букв, цифр или подчеркиваний@— символ "собаки"\.— экранированная точка (без экрана точка означает "любой символ")
Для повторяющихся вызовов лучше создать объект Regex, чтобы избежать повторной компиляции шаблона:
Regex emailRegex = new Regex(@"\w+@\w+\.\w+");
Console.WriteLine(emailRegex.IsMatch("admin@site.ru")); // True
2. Поиск всех совпадений: Match и MatchCollection
Метод Match возвращает первое совпадение, а Matches — все совпадения в виде коллекции MatchCollection. Каждый объект Match содержит информацию о найденной подстроке, ее позиции и длине.
Пример: извлечение всех чисел из строки
string data = "В 2023 году было 15 событий, в 2024 — уже 23.";
string numberPattern = @"\d+"; // одна или более цифр
MatchCollection matches = Regex.Matches(data, numberPattern);
foreach (Match match in matches)
{
Console.WriteLine($"Найдено: {match.Value} на позиции {match.Index}");
}
// Вывод:
// Найдено: 2023 на позиции 2
// Найдено: 15 на позиции 20
// Найдено: 2024 на позиции 34
// Найдено: 23 на позиции 47
Работа с группами (Group). Группы позволяют извлекать части совпадения. Например, при поиске даты в формате "дд.мм.гггг" можно отдельно получить день, месяц и год:
string input = "Сегодня 25.12.2024";
string datePattern = @"(\d{2})\.(\d{2})\.(\d{4})";
Match match = Regex.Match(input, datePattern);
if (match.Success)
{
Console.WriteLine($"День: {match.Groups[1].Value}"); // 25
Console.WriteLine($"Месяц: {match.Groups[2].Value}"); // 12
Console.WriteLine($"Год: {match.Groups[3].Value}"); // 2024
}
Группы нумеруются с 1 (группа 0 — все совпадение целиком). Именованные группы удобнее читать:
string namedPattern = @"(?<day>\d{2})\.(?<month>\d{2})\.(?<year>\d{4})";
match = Regex.Match(input, namedPattern);
Console.WriteLine(match.Groups["day"].Value); // 25
3. Продвинутые возможности: замены и опции
Замена текста с помощью Regex.Replace. Позволяет не только удалить или заменить подстроку, но и использовать группы в строке замены:
string phone = "+7 (123) 456-78-90";
// Убираем всё, кроме цифр
string clean = Regex.Replace(phone, @"[^\d]", "");
Console.WriteLine(clean); // 71234567890
// Меняем формат: (123) 456-78-90 → 123-456-7890
string formatted = Regex.Replace(phone,
@"\((\d{3})\)\s*(\d{3})-(\d{2})-(\d{2})",
"$1-$2-$3$4");
Console.WriteLine(formatted); // 123-456-7890
Важные опции (RegexOptions):
IgnoreCase— игнорировать регистрMultiline— ^ и $ работают для каждой строки, а не всего текстаCompiled— ускоряет выполнение за счет предварительной компиляцииExplicitCapture— только именованные группы считаются захватывающими
Пример с опциями:
string text = "C# и c# — один язык";
string pattern = @"c#";
// Поиск без учета регистра
MatchCollection matches = Regex.Matches(text, pattern, RegexOptions.IgnoreCase);
Console.WriteLine(matches.Count); // 2
4. Практические примеры для повседневных задач
Валидация email (упрощенный вариант):
public static bool IsValidEmail(string email)
{
string pattern = @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$";
return Regex.IsMatch(email, pattern);
}
Console.WriteLine(IsValidEmail("user@domain.com")); // True
Извлечение URL из текста:
string text = "Сайт: https://example.com/path?q=1 и http://test.org";
string urlPattern = @"https?://[^\s]+";
MatchCollection urls = Regex.Matches(text, urlPattern);
foreach (Match url in urls)
Console.WriteLine(url.Value);
// https://example.com/path?q=1
// http://test.org
Проверка сложности пароля:
public static bool IsStrongPassword(string password)
{
// Минимум 8 символов, хотя бы одна заглавная, одна строчная, одна цифра, один спецсимвол
string pattern = @"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\da-zA-Z]).{8,}$";
return Regex.IsMatch(password, pattern);
}
Console.WriteLine(IsStrongPassword("Pass123!")); // True