Рубріки: Теория

Регулярные выражения в C# (C# regex)

Сергій Бондаренко

Регулярные выражения (C# regex) — это шаблоны поиска строк. Они применяются для всевозможных операций, связанных с манипулированием текста, например, поиском подстрок и их заменой. 

Содержание статьи:

1. Что такое регулярные выражения в C# (C# regex)

2. Удаление двойных пробелов методом Replace

3. Подсчет повторений в тексте с помощью Regex

4. Проверяем формат телефонного номера с помощью регулярных выражений

5. Валидация электронной почты

6. Применение Regex к парсингу XML на примере веб-клиента

7. Написание утилиты WHOIS

8. Проверка ввода IP-адреса

9. Заключение

Что такое регулярные выражения в C#

Все регулярные выражения выглядят как обычные строки, наполненные специальными символами. Эти символы могут быть двух видов: метасимволы и квантификаторы.

Метасимволы — это шаблоны, которые используются для поиска. Если вы работали в DOS, то вам должны быть знакомы ключи, которые, скажем, позволяют выделять группы файлов. Например, использование звездочки с расширением, например, *.png, позволяет выделить все файлы этого типа. Метасимволы работают по тому же принципу, выступая шаблоном для текста. 

Метасимвол Значение
\d Шаблон для символов цифр.
\D Указывает любой символ, отличный от цифры.
\w Шаблон для указания любого символа цифры, буквы или подчеркивания.
\W Шаблон для указания любого символа цифры, кроме буквы или подчеркивания.
\s Шаблон для определения любого печатного символа, например, пробела.
Определяет любой символ кроме табуляции, новой строки.
. Указывает на любой символ, кроме символа строки.
\. Определяет символ строки.

Квантификаторы определяют в шаблоне, где и какое количество раз должны встречаться символы.

Квантификатор Значение
^ Начало строки. Например, ^http: означает соответствие для http, только если этот элемент находится в начале строки.
$

 

Определение конца строки.
+ Одно и более вхождений шаблона в строке.
| Символ для варианта маски — справа или слева.

Перед объявлением регулярного выражения необходимо указать директиву using System.Text.RegularExpressions;.

Чтобы задействовать в коде инструмент для регулярных выражений, следует создать экземпляр класса regex и в качестве параметра его конструктора передать его регулярное выражение. Одно из самых популярных применений этого инструмента — для верификации правильности введенных данных. Телефонные номера, почтовые адреса (например, названия улиц), имена ящиков электронной почты, номера платежных поручений и так далее. 

Удаление двойных пробелов с помощью метода Replace

В разных задачах используется такая полезная возможность регулярных выражений как метод 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 нам бы пришлось принимать это предложение за массив слов,  разбивать его на элементы, ориентируясь на пробелы и учитывая знаки препинания. С 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 к парсингу XML на примере веб-клиента

Хороший практический пример для использования 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; //поиск первой группы 
        }
    }
}

Результат выполнения кода:

Результат выполнения кода

Написание утилиты WHOIS

Другой пример избирательного отбора текста из 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-адреса

Давайте несколько усовершенствуем наше приложение, и защитим поле ввода 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#:

Останні статті

Обучение Power BI – какие онлайн курсы аналитики выбрать

Сегодня мы поговорим о том, как выбрать лучшие курсы Power BI в Украине, особенно для…

13.01.2024

Work.ua назвал самые конкурентные вакансии в IТ за 2023 год

В 2023 году во всех крупнейших регионах конкуренция за вакансию выросла на 5–12%. Не исключением…

08.12.2023

Украинская IT-рекрутерка создала бесплатный трекер поиска работы

Unicorn Hunter/Talent Manager Лина Калиш создала бесплатный трекер поиска работы в Notion, систематизирующий все этапы…

07.12.2023

Mate academy отправит работников в 10-дневный оплачиваемый отпуск

Edtech-стартап Mate academy принял решение отправить своих работников в десятидневный отпуск – с 25 декабря…

07.12.2023

Переписки, фото, история браузера: киевский программист зарабатывал на шпионаже

Служба безопасности Украины задержала в Киеве 46-летнего программиста, который за деньги устанавливал шпионские программы и…

07.12.2023

Как вырасти до сеньйора? Девелопер создал популярную подборку на Github

IT-специалист Джордан Катлер создал и выложил на Github подборку разнообразных ресурсов, которые помогут достичь уровня…

07.12.2023