MyTetra Share
Делитесь знаниями!
Регулярные выражения REGEX
Время создания: 18.09.2019 22:05
Текстовые метки: regex, c#, регулярные выражения
Раздел: Компьютер - C# - REGEX
Запись: Kozlov-AE/Tetra/master/base/1568833510zvtqjw2fsf/text.html на raw.githubusercontent.com

Регулярные выражения в Си-шарп. Класс 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 предоставляет различную информацию о подстроке – длину, индекс, само значение и другое.

static void Main(string[] args)
{
   string data1 = "Петр, Андрей, Николай";
   Regex myReg = new Regex("Николай");
   Match match = myReg.Match(data1);
   Console.WriteLine(match.Value); // "Николай"
   Console.WriteLine(match.Index); // 14
   Console.ReadKey();
}


Matches – возвращает все подстроки соответствующие шаблону в виде коллекции типа MatchCollection. Каждый элемент этой коллекции типа Match.

static void Main(string[] args)
{
   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); //вывод всех подстрок "Николай"
   Console.ReadKey();
}


Replace – возвращает строку, в которой заменены все подстроки, соответствующие шаблону, новой строкой:

static void Main(string[] args)
{
   string data1 = "Петр, Николай, Андрей, Николай";
   Regex myReg = new Regex("Николай");
   data1 = myReg.Replace(data1, "Максим");
   Console.WriteLine(data1); //"Петр, Максим, Андрей, Максим"
   Console.ReadKey();
}


Split - возвращает массив строк, полученный в результате разделения входящей строки в местах соответствия шаблону регулярного выражения:

static void Main(string[] args)
{
   string data1 = "Петр,Николай,Андрей,Николай";
   Regex myReg = new Regex(",");
   string[] names = myReg.Split(data1); // массив имен
   Console.ReadKey();
}


Специальные символы
В примерах выше рассматривались очень простые, однозначные регулярные выражения без использования спецсимволов. Спецсимволов существует достаточно много, их описание приведу ниже в таблицах:

Классы символов

Обозначение

Описание

Шаблон

Соответствие

[группа_символов]

Любой из перечисленных в скобках символов. Используя тире можно указать диапазон символов, например, [a-f] - то же самое, что [abcdef]

[abc]

«a» в «and»

[^группа_символов]

Любой символ, кроме перечисленных в скобках

[^abc]

«n», «d» в «and»

\d

Цифра. Эквивалентно [0-9]

\d

«1» в «data1»

\D

Любой символ, кроме цифр. Эквивалентно [^0-9]

\D

«y» в «2014y»

\w

Цифра, буква (латинский алфавит) или знак подчеркивания. Эквивалентно [0-9a-zA-Z_]

\w

«1», «5», «с» в «1.5с»

\W

Любой символ, кроме цифр, букв (латинский алфавит) и знака подчеркивания. Эквивалентно [^0-9a-zA-Z_]

\W

«.» в «1.5с»

\s

Пробельный символ (пробел, табуляция, перевод строки и т. п.)

\s

« » в «c sharp»

\S

Любой символ, кроме пробельных

\S

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

.

Любой символ, кроме перевода строки. Для поиска любого символа, включая перевод строки, можно использовать конструкцию [\s\S]

c.harp

«csharp» в «mycsharp»


Символы повторения

Обозначение

Описание

Шаблон

Соответствие

*

Соответствует предыдущему элементу ноль или более раз

\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»

{n,}

Соответствует предыдущему элементу, который повторяется минимум n раз

\d{2,}

«43», «546», «82» в «2,43,546,82»

{n,m}

Соответствует предыдущему элементу, который повторяется минимум n раз и максимум m

\d{2,}

«43», «546», «821» в
«2,43,546,8212»


Символы привязки

Обозначение

Описание

Шаблон

Соответствие

^

Соответствие должно находиться в начале строки

^\d{2}

«32» в «32,43,54»

$

Соответствие должно находиться в конце строки или до символа \n при многострочном поиске

\d{2}$

«54» в «32,43,54»

\b

Соответствие должно находиться на границе алфавитно-цифрового символа (\w) и не алфавитно-цифрового (\W)

\b\d{2}

«32», «54» в «32 a43 54»

\B

Соответствие не должно находиться на границе

\B\d{2}

«43» в «32 a43 54»

\G

Соответствие должно находиться на позиции конца предыдущего соответствия

\G\d

«3», «2», «4» в «324.758»


Символы выбора

Обозначение

Описание

Шаблон

Соответствие

|

Работает как логическое «ИЛИ» - соответствует первому и/или второму шаблону

one|two

«one», «two» в «one two three»

(группа_символов)

Группирует набор символов в единое целое для которого дальше могут использоваться + * ? и т.д. Каждой такой группе назначается порядковый номер слева направо начиная с 1. По этому номеру можно ссылаться на группу \номер_группы

(one)\1

«oneone» в «oneone onetwoone»

(?:группа_символов)

Та же группировка только без назначения номера группы

(?:one){2}

«oneone» в «oneone onetwoone»


Другие символы

Обозначение

Описание

Шаблон

Соответствие

\t

Символ табуляции

\t

\v

Символ вертикальной табуляции

\v

\r

Символ возврата каретки

\r

\n

Символ перевода строки

\n

\f

Символ перевода страницы

\f

\

Символ, который позволяет экранировать специальные символы, чтобы те воспринимались буквально. Например, чтобы было соответствие символу звёздочки, шаблон будет выглядеть так \*

\d\.\d

«1.1», «1.2» в «1.1 1.2»


В этих таблицах представлены далеко не все элементы языка регулярных выражений, но их вполне достаточно для больших возможностей.

Приведу пример программы, которая проверят корректность электронного адреса (шаблон тот же, что и на странице регистрации на этом сайте):

static void Main(string[] args)
{
   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
   Console.ReadKey();
}


Здесь перед началом строки регулярного выражения стоит символ «@» который указывает комплятору воспринимать все символы буквально. Это необходимо, чтобы корректно воспринимался символ «\».

Параметры поиска

Здесь мы поговорим о втором конструкторе 
Regex, который принимает в качестве второго аргумента значение перечисления RegexOptions. В этом перечисление есть следующие значения:

IgnoreCase – игнорирование регистра при поиске. Находит соответствия независимо прописными или строчными буквами в строке написано слово;
RightToLeft – поиск будет выполнен справа налево, а не слева направо;
Multiline – многострочный режим поиска. Меняет работу спецсимволов «^» и «$» так, что они соответствуют началу и концу каждой строки, а не только началу и концу целой строки;
Singleline – однострочный режим поиска;
CultureInvariant - игнорирование национальных установок строки;
ExplicitCapture – обеспечивается поиск только буквальных соответствий;
Compiled – регулярное выражение компилируется в сборку, что делает более быстрым его исполнение но увеличивает время запуска;
IgnorePatternWhitespace – игнорирует в шаблоне все неэкранированные пробелы. С этим параметром шаблон «a b» будет аналогичным шаблону «ab»;
None – использовать поиск по умолчанию.

Пример программы с использованием параметра поиска (игнорирование регистра):

static void Main(string[] args)
{
   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
   Console.ReadKey();
}


Если необходимо установить несколько параметров, тогда они разделяются оператором поразрядного «ИЛИ» - «|»

Regex myReg = new Regex(@"Sergey", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);

Приведу еще один пример использования регулярных выражений. Создадим метод, который будет принимать ссылку, а возвращать только доменное имя:

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();
}

Так же в этом разделе:
 
MyTetra Share v.0.59
Яндекс индекс цитирования