Download as pdf or txt
Download as pdf or txt
You are on page 1of 8

Лекція 8.

Регулярні вирази в Сі-Шарп. Клас Regex


Мета: розглянути потужний, широко використовуваний інструмент для
обробки тексту - регулярні вирази.
Регулярний вираз - це шаблон, складений з символів і спеціальних
символів, який дозволяє знаходити підрядки відповідні цим шаблоном в інших
рядках. Спеціальних символів та різних правил їх комбінування є дуже багато, тому
регулярні вирази можна навіть назвати окремою мовою програмування. Ті, хто
користувався пошуком по файлах в Windows можуть знати, що для того щоб знайти
файли тільки заданого розширення, задається шаблон типу «* .txt». Тут «*» -
спеціальний символ, який означає будь-які імена файлів. Так ось регулярні вирази
надають подібний механізм.
Регулярні вирази надають масу можливостей:
— Замінювати в рядку всі однакові слова іншим словом, або видаляти такі
слова;
— Виділяти з рядка необхідну частину. Наприклад, з будь-якого посилання
(http://mycsharp.ru/post/33/2013_10_19_virtualnye_metody_v_si-
sharp_pereopredelenie_metodov.html) виділяти тільки доменну частину
(mycsharp.ru);
— Перевіряти чи відповідає рядок заданим шаблоном. Наприклад, перевіряти,
чи правильно введено email, телефон т.д.;
— Перевіряти, чи містить рядок заданий підрядок;
— Отримувати з рядка всі входження підрядка, відповідні шаблону регулярного
виразу. Наприклад, отримати всі дати з рядка.

Початок роботи з регулярними виразами


Для того, щоб працювати з регулярними виразами необхідно підключити на
початку програми простір імен:

using System.Text.RegularExpressions;

У Сі-Шарп роботу з регулярними виразами надає клас Regex. Створення


регулярного виразу має наступний вигляд:

Regex myReg = new Regex ([шаблон]);

Тут [шаблон] - це рядок містить символи та спеціальні символи.


У Regex також є і другий конструктор, який приймає додатковий параметр -
опції пошуку.
Простий приклад програми з використанням регулярних виразів:

static void Main(string[] args)


{
string data1 = "Петро, Андрій, Микола";
string data2 = "Петро, Андрій, Олександр";
Regex myReg = new Regex("Микола"); // Створення регулярного виразу
Console.WriteLine(myReg.IsMatch(data1)); // True
Console.WriteLine(myReg.IsMatch(data2)); // False
Console.ReadKey();
}

Тут як шаблон виступає однозначний рядок "Микола". Далі був


використаний метод IsMatch, який перевірять, містить заданий рядок (data1, data2)
підрядок відповідно до шаблону.

Методи класу Regex

Розглянемо коротко методи для роботи з регулярними виразами:


IsMatch - перевіряє чи містить рядок хоча б один підрядок відповідно до
шаблону регулярного виразу. Робота цього методу показана у прикладі вище.
Match - повертає перший підрядок, відповідно до шаблону, у вигляді об'єкта
класу Match. Клас Match надає різну інформацію про підрядок, такі як довжину,
індекс, саме значення та інше.

string data1 = "Петро, Андрій, Микола";


Regex myReg = new Regex("Микола");
Match match = myReg.Match(data1);
Console.WriteLine(match.Value); // "Микола"
Console.WriteLine(match.Index); // 14

Matches - повертає всі підрядки відповідно до шаблону у вигляді колекції


типу MatchCollection. Кожен елемент цієї колекції має тип Match.
string data1 = "Петро, Микола, Андрій, Микола";
Regex myReg = new Regex("Микола");
MatchCollection matches = myReg.Matches(data1);
Console.WriteLine(matches.Count); // 2
foreach (Match m in matches)
{
Console.WriteLine(m.Value); // Виведення всіх підрядків "Микола"
}

Replace – пошук-заміна, цей метод повертає рядок, в якому замінені всі


підрядки, відповідно до шаблону, новим рядком:
string data1 = "Петро, Микола, Андрій, Микола";
Regex myReg = new Regex("Микола");
data1 = myReg.Replace(data1, "Максим");
Console.WriteLine(data1); // "Петро, Максим, Андрій, Максим"

Split - повертає масив рядків, отриманий в результаті поділу рядка в місцях


відповідності шаблону регулярного виразу:
string data1 = "Петро, Микола, Андрій, Микола";
Regex myReg = new Regex(",");
string[] names = myReg.Split(data1); // Масив імен
foreach (var s in names)
{
Console.WriteLine(s); // Виведення всіх підрядків
}
Спеціальні символи
У прикладах вище розглядалися дуже прості, однозначні регулярні вирази
без використання спеціальних символів. Цих спецсимволів існує досить багато, їх
опис приведено нижче в таблицях:
Класи символів
Позначення Опис Шаблон Знаходить

Будь-який з перерахованих в дужках символів. За


[Група_символів] допомогою тире можна вказати діапазон символів, [abc] «a» в «and»
наприклад, [a-f] – це те ж саме, що [abcdef]

[^Група_символів] Будь-який символ, крім перерахованих в дужках [^abc] «n», «d» в «and»

\d Цифра. Еквівалентно [0-9] \d "1" в "data1»

\D Будь-який символ, крім цифр. Еквівалентно [^0-9] \D «y» в «2014y»

\w Цифра, літера або знак підкреслення. \w «1», «5», «c» в «1.5с»

Будь-який символ, крім цифр, букв і знаку


\W \W «.» у «1.5с»
підкреслення.

Пробільний символ (пробіл, табуляція, новий


\s \s « » в «c sharp»
рядок і т. g.)

«c» «s» «h» «a» «r» «p» в


\S Будь-який символ, крім пробільного \S
«c sharp»

Будь-який символ, крім нового рядка. Для пошуку


. будь-якого символу, включаючи новий рядок, c.harp «csharp» в «mycsharp»
можна використовувати конструкцію [\s\S]

Символи повторення
Позначення Опис Шаблон Приклад

* Повторює попередній елемент нуль або більше разів \d* «a», «1b», «23c» в «a1b23c»

+ Повторює попередній елемент один або більше разів \d+. «1b», «23c» в «a1b23c»

? Повторює попередній елемент нуль або один раз \d?\D «a», «1b», «3с» в «a1b23c»

{n} Повторює попередній елемент рівно n раз \d{2} «43», «54», «82» в «2,43,546,82»

Повторює попередній елемент, який повторюється «43», «546», «82» в


{n,} \d{2,}
мінімум n раз «2,43,546,82»
Повторює попередній елемент, який повторюється «43», «546», «821»
{n, m} \d{2,}
мінімум n раз і максимум m в «2,43,546,8212»

Символи прив'язки
Позначення Опис Шаблон Відповідність

^ Шукати з початку рядка ^\d{2} «32» в «32,43,54»

$ Шукати в кінці рядка \d{2}$ «54» в «32,43,54»

Відповідність має перебувати між буквою (\w) і не буквою «32», «54» в «32
\b \b\d{2}
(\W) a43 54»

\B Відповідність не повинна знаходитися на межі \B\d{2} «43» в «32 a43 54»

Відповідність має перебувати на позиції кінця попередньої "3", "2", "4" в


\G \G\d
відповідності "324.758"

Cимволи вибору
Позначення Опис Шаблон Відповідність

Працює як логічне «АБО» - відповідає першому і / або «one», «two» в


| one|two
другому шаблоном «one two three»

Групуються набір символів в єдине ціле для якого далі


можуть використовуватися + *? і т.д. Кожній такій групі «oneone» в
(Група_символів) призначається порядковий номер зліва направо (one)\1 «oneone
починаючи з 1. За цим номером можна посилатися на onetwoone»
групу \номер_группи

«oneone» в
(?:Група_символів) Теж тільки без призначення номера групи (?:One){2} «oneone
onetwoone»

Інші символи
Позначення Опис Шаблон Відповідність

\t Символ табуляції \t

\v Символ вертикальної табуляції \v

\r Символ повернення каретки \r

\n Символ переводу рядка \n


\f Символ переводу сторінки \f

Символ, який дозволяє екранувати спеціальні символи, щоб ті


"1.1», «1.2» в
\ сприймалися буквально. Наприклад, щоб була відповідність \d\.\d
«1.1 1.2»
символу зірочки, шаблон буде виглядати так \*

У цих таблицях представлені далеко не всі елементи мови регулярних


виразів, але їх цілком достатньо. Приклад програми, яка перевірять правильність
електронної адреси:
Regex myReg = new Regex (
@"[A-Za-z]+[\.A-Za-z0-9_-]*[A-Za-z0-9]+@[A-Za-z]+\.[A-Za-z]+");
Console.WriteLine (myReg.IsMatch ( "email@email.com")); // True
Console.WriteLine (myReg.IsMatch ( "email@email")); // False
Console.WriteLine (myReg.IsMatch ( "@email.com")); // False

Перед початком рядка регулярного виразу варто символ «@» який вказує
компілятору сприймати всі символи буквально. Це необхідно, щоб сприймався
символ «\».

Параметри пошуку
Другий конструкторі Regex приймає в якості другого аргументу значення
перерахування RegexOptions, У цьому перерахування є наступні значення:
IgnoreCase - ігнорування регістра при пошуку. Знаходить відповідності
незалежно великими або малими літерами в рядку написано слово;
RightToLeft - пошук буде виконаний справа наліво, а не зліва направо;
Multiline - багаторядковий режим пошуку. Змінює роботу спецсимволів «^»
і «$» так, що вони відповідають початку і кінця кожного рядка, а не тільки початку
і кінця цілої рядки;
Singleline - однорядковий режим пошуку;
CultureInvariant - ігнорування національних установок рядки;
ExplicitCapture - забезпечується пошук тільки буквальних відповідностей;
Compiled - регулярний вираз компілюється в збірку, що робить більш
швидким його виконання але збільшує час запуску;
IgnorePatternWhitespace - ігнорує в шаблоні всі неекрановані пробіли. З
цим параметром шаблон «a b» буде аналогічним шаблоном «ab»;
None - використовувати пошук за замовчуванням.
Приклад програми з використанням параметра пошуку (ігнорування
регістра):
string data = "nikolay, sergey, oleg";
Regex myRegIgnoreCase = new Regex (@"Sergey", RegexOptions.IgnoreCase);
Regex myReg = new Regex (@"Sergey");
Console.WriteLine (myRegIgnoreCase.IsMatch (data)); // True
Console.WriteLine (myReg.IsMatch (data)); // False

Якщо необхідно встановити кілька параметрів, тоді вони поділяються


оператором поразрядного «АБО» - «|»
Regex myReg = new Regex (@"Sergey",
RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);

Приклад використання регулярних виразів. Створимо метод, який буде


приймати посилання, а повертати тільки доменне ім'я:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace ConsoleApplication19
{
class Program
{

public static string GetDomain(string url)


{
Regex re = new Regex("http://", RegexOptions.IgnoreCase);
url = re.Replace(url, ""); // Видаляємо частину http://
Regex reWww = new Regex(@"www\.", RegexOptions.IgnoreCase);
url = reWww.Replace(url, ""); // Видаляємо частину www.
int end = url.IndexOf("/");
if (end != -1)
url = url.Substring(0, end);
return url;
}
static void Main(string[] args)
{
string url1 =
"http://mycsharp.ru/post/33/2013_10_19_virtualnye_metody_v_si-
sharp_pereopredelenie_metodov.html";
string url2 =
"http://www.mycsharp.ru/post/33/2013_10_19_virtualnye_metody_v_si-
sharp_pereopredelenie_metodov.html";
Console.WriteLine(GetDomain(url1)); // mycsharp.ru
Console.WriteLine(GetDomain(url2)); // mycsharp.ru
Console.ReadKey();
}

}
}

Завдання
1. Створіть програму, яка буде перевіряти коректність введення логіна.
Коректним логіном буде рядок від 2-х до 10-ти символів, що містить тільки літери
і цифри, і при цьому цифра не може бути першою.
2. Створіть фільтр. Метод буде приймати вихідний рядок, і повертати
результат, де погані слова будуть замінені на «цензура». Обробіть хоча б одне таке
слово, тільки передбачте безліч його форм.

You might also like