Регулярные выражения (C# regex) — это шаблоны поиска строк. Они применяются для всевозможных операций, связанных с манипулированием текста, например, поиском подстрок и их заменой.
Содержание статьи:
1. Что такое регулярные выражения в C# (C# regex)
2. Удаление двойных пробелов методом Replace
3. Подсчет повторений в тексте с помощью Regex
4. Проверяем формат телефонного номера с помощью регулярных выражений
5. Валидация электронной почты
6. Применение Regex к парсингу XML на примере веб-клиента
Все регулярные выражения выглядят как обычные строки, наполненные специальными символами. Эти символы могут быть двух видов: метасимволы и квантификаторы.
Метасимволы — это шаблоны, которые используются для поиска. Если вы работали в DOS, то вам должны быть знакомы ключи, которые, скажем, позволяют выделять группы файлов. Например, использование звездочки с расширением, например, *.png
, позволяет выделить все файлы этого типа. Метасимволы работают по тому же принципу, выступая шаблоном для текста.
Метасимвол | Значение |
\d | Шаблон для символов цифр. |
\D | Указывает любой символ, отличный от цифры. |
\w | Шаблон для указания любого символа цифры, буквы или подчеркивания. |
\W | Шаблон для указания любого символа цифры, кроме буквы или подчеркивания. |
\s | Шаблон для определения любого печатного символа, например, пробела. |
| Определяет любой символ кроме табуляции, новой строки. |
. | Указывает на любой символ, кроме символа строки. |
\. | Определяет символ строки. |
Квантификаторы определяют в шаблоне, где и какое количество раз должны встречаться символы.
Квантификатор | Значение |
^ | Начало строки. Например, ^http: означает соответствие для http, только если этот элемент находится в начале строки. |
$
| Определение конца строки. |
+ | Одно и более вхождений шаблона в строке. |
| | Символ для варианта маски — справа или слева. |
Перед объявлением регулярного выражения необходимо указать директиву using System.Text.RegularExpressions;
.
Чтобы задействовать в коде инструмент для регулярных выражений, следует создать экземпляр класса regex
и в качестве параметра его конструктора передать его регулярное выражение. Одно из самых популярных применений этого инструмента — для верификации правильности введенных данных. Телефонные номера, почтовые адреса (например, названия улиц), имена ящиков электронной почты, номера платежных поручений и так далее.
В разных задачах используется такая полезная возможность регулярных выражений как метод Replace.
Replace работает следующим образом: берет строку, применяет к ней шаблон, после чего заменяет по шаблону на нужный текст.
Благодаря этому методу из любого текста можно автоматически удалять двойные пробелы, которые случайно появились в процессе набора:
class zamenaprobela { static void Main(string[] args) { string fragment = "Когда-нибудь мы с тобой обязательно встретимся "; // текст с двойными пробелами string pattern = @"\s+"; // маска-шаблон для замены string target = " "; // на что меняем Regex shabl = new Regex(pattern); // создание маски для замены string result = shabl.Replace(fragment, target); // замена по шаблону { Console.WriteLine(result); // вывод результата } } }
Результат:
Представьте себе задачу, когда нужно подсчитать количество определенных слов в предложении. Без regex
нам бы пришлось принимать это предложение за массив слов, разбивать его на элементы, ориентируясь на пробелы и учитывая знаки препинания. С regex
эта задача решается намного проще.
Создадим простое приложение, которое будет считать повторение заданного фрагмента. Воспользуемся Windows Forms и добавим простенький интерфейс из двух текстовых полей ввода и кнопки. В первом поле мы будем вводить исходный текст, во втором — фрагмент, который нужно найти. Программа подсчитает количество встречаемых фрагментов и выведет результат в первое поле вместо исходного текста.
Например, если в скороговорке «Вез корабль карамель, наскочил корабль на мель, матросы две недели карамель на мели ели» мы станем искать, сколько раз встречается слово «карамель», программа выведет число два, если будем проверять сочетание букв «ел» — то шесть.
using System.Windows.Forms; namespace WindowsFormsApp1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { string line = textBox1.Text; Regex regex = new Regex(textBox2.Text); MatchCollection match = regex.Matches(line); textBox1.Text = match.Count.ToString(); } private void textBox2_TextChanged(object sender, EventArgs e) { } } }
Результат выполнения кода:
Результат выполнения кода
Ниже — пример похожей программы. Она показывает в консоли обнаруженные в исходном фрагменте словоформы слова «мель»:
namespace ConsoleAppTexttoconsole { class Program { static void Main(string[] args) { string s = "Вез корабль карамель, наскочил корабль на мель, матросы две недели карамель на мели ели"; Console.WriteLine(s); Regex regex = new Regex(@"мел(\w*)"); MatchCollection matches = regex.Matches(s); if (matches.Count > 0) { foreach (Match match in matches) Console.WriteLine(match.Value); } else { Console.WriteLine("Указанного буквенного сочетания в тексте нет"); } } } }
Результат:
Предположим, нам необходимо выполнить проверку вводимых данных. Пусть это будет телефонный номер. Он должен вводиться по строгому стандарту, не иметь лишних цифр XXX-XX-XX:
class Program { static void Main(string[] args) { string number_tel = "131-52-54"; Regex proverka = new Regex (@"^\d{3}-\d{2}-\d{2}"); MatchCollection matches = proverka.Matches(number_tel); if (matches.Count > 0) { foreach (Match match in matches) Console.WriteLine("Телефонный номер введен корректно"); } else { Console.WriteLine("Номер введен некорректно"); } } }
Результат:
Но эта утилита имеет одну неточность — телефонный номер не должен начинаться с нуля, а также не может быть единицей. Поэтому исправляем параметр regex
, дополнительно указывая диапазон допустимых значений. Также отдельно пропишем маску для первой цифры, так как она отличается от остальных:
Regex proverka = new Regex(@"[2-9]{1}[0-9]{2}-[0-9]{2}-[0-9]{2}");
Другой пример использования инструмента regex
— ввод email-адреса по форме. То есть имя электронной почты не должно начинаться, скажем, с подчеркивания или содержать скобки, не может иметь более двух знаков @
и тому подобное. Для такой задачи задействуем инструмент regex
, прописав для него соответствующий шаблон:
namespace ConsoleAppCheckemail class Program { static void Main(string[] args) { string shablon_email = @"^(?("")(""[^""]+?""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" + @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9]{2,17}))$"; while (true) { Console.WriteLine("Укажите email"); string email = Console.ReadLine(); if (Regex.IsMatch(email, shablon_email, RegexOptions.IgnoreCase)) { Console.WriteLine("Адрес электронной почты" + email + " введен верно"); break; } else { Console.WriteLine("Введенный адрес электронной почты " + email + " некорректен"); } } } } }
Результат выполнения кода:
В этом коде для маски мы указали переменную shablon email
, а также использовали статистический метод сравнения IsMatch
.
Хороший практический пример для использования regex
— веб-клиент для получения курса доллара. Для этого нам нужно выполнить парсинг сайта-источника, например, центробанка. Есть два пути решения этой задачи. Первый вариант — «в лоб». Можно выполнить парсинг всей титульной страницы Центробанка и искать в ее коде нужную информацию. Но это не самый лучший вариант, потому что титульная страница сайта громоздкая и содержит массу лишней информации.
Поэтому обратимся к API сайта, поискав его через Google. На странице можно увидеть ссылки на краткие xml и json — файлы с котировками. Возьмем одну из таких ссылок — https://www.cbr.ru/scripts/XML_daily_eng.asp. Ее код содержит исключительно информацию, которая относится к курсу валют.
Теперь создадим простой интерфейс Windows Forms с кнопкой и объектом типа label
, где будет отображаться курс. Поскольку мы будем иметь дело с веб-загрузкой и регулярными выражениями, указываем заранее пространства имен using System.Net;
и using System.Text.RegularExpressions;
.
Далее обращаемся к отладчику событий (просто кликните по кнопке) и пишем наш клиент:
namespace WinFormsApp7 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { string line = ""; using (WebClient wc = new WebClient()) // Используем для отправки запросов line = wc.DownloadString("https://www.cbr.ru/scripts/XML_daily_eng.asp"); // Ссылка из API сайта на котировки валют Match match = Regex.Match(line, "<Name>US Dollar</Name><Value>(.*?)</Value>"); //определение группы label1.Text = match.Groups[1].Value; //поиск первой группы } } }
Результат выполнения кода:
Результат выполнения кода
Другой пример избирательного отбора текста из XML-файла — простая утилита Whois для определения IP-адреса. Ее код будет похож на тот, что был в прошлой задаче, за исключением маски, определяющей место парсинга API-данных и адреса служебного XML-файла. Создайте шаблон Windows Forms и добавьте на него кнопку labelBox
(для вывода страны) и TextBox
(для IP-адреса):
using System; //Перечисление используемых пространств имен using System.Net; //Перечисление используемых пространств имен using System.Text.RegularExpressions; //Перечисление используемых пространств имен using System.Windows.Forms; //Перечисление используемых пространств имен namespace WinFormsApp9 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { string line = ""; using (WebClient wc = new WebClient()) // Используем для отправки запросов line = wc.DownloadString($"http://ipwhois.app/xml/{textBox1.Text}"); // Ссылка из API сайта-сервиса WHOIS Match match = Regex.Match(line, "<country>(.*?)</country>"); //выделение страны из текста label1.Text = match.Groups[1].Value; //поиск первой группы } } }
Результат выполнения кода:
Результат выполнения кода
Давайте несколько усовершенствуем наше приложение, и защитим поле ввода IP-адреса от случайных и неверных абракадабр. В этом нам тоже поможет инструмент регулярных выражений regex
.
В свойствах объекта textBox
щелкните два раза на событии TextChanged
. Переходим к описанию этого события. Оно возникает, когда в этом элементе изменяется значение свойства текста, то есть при вводе текста происходит событие. Опишем такое событие на вводимый текст. Пусть это будет условие, при котором если вводимый символ не является точкой или цифрой, программа моментально удалить его, выдав сообщение об ошибке. При этом изменится положение курсора, поэтому дополнительно передвинем его по всей длине текста:
namespace WinFormsApp9 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { string line = ""; using (WebClient wc = new WebClient()) // Используем для отправки запросов line = wc.DownloadString($"http://ipwhois.app/xml/{textBox1.Text}"); // Ссылка из API сайта-сервиса WHOIS Match match = Regex.Match(line, "<country>(.*?)</country>"); //выделение страны из текста label1.Text = match.Groups[1].Value; //поиск первой группы } private void textBox1_TextChanged(object sender, EventArgs e) { if (Regex.IsMatch(textBox1.Text, "[^0-9-.|]")) // Условие регулярного выражения { MessageBox.Show("Неправильный ввод адреса!", Text, MessageBoxButtons.OK, MessageBoxIcon.Asterisk); // Предупреждение о неправильном вводе textBox1.Text = textBox1.Text.Remove(textBox1.Text.Length - 1); // Удаление некорректного символа textBox1.SelectionStart = textBox1.TextLength; // Возвращение позиции курсора } } } }
Результат выполнения кода:
Результат работы программы#
Как видите, в регулярных выражениях нет ничего сложного, но их применение требует от программиста внимательности. Инструменты regex
применяются во многих задачах, а потому поддерживаются любыми языками программирования, конечно, со своими особенностями синтаксиса.
Чтобы хорошо ориентироваться в паттернах для замены и редактирования данных рекомендуем вам более детально изучить синтаксис шаблонов.
Также советуем посмотреть видео, где рассказывается про основные понятия о регулярных выражениях C#:
Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…
Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…
Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…
В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…
Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…
Дедлайн (от англ. deadline — «крайний срок») — это конечная дата стачи проекта или задачи…