Регулярные выражения
Регулярное выражение – это некий шаблон, составленный из символов и спецсимволов, который позволяет находить подстроки соответствующие этому шаблону в других строках.
Классы, предназначенные для работы с регулярными выражениями, содержатся в сборке System.dll и описаны в пространстве имен System.Text.RegularExpressions. Основным классом, обеспечивающим реализацию всех действий, связанных с использованием регулярных выражений (поиск, замена, разбиение строки), является класс Regex. Все прочие классы являются вспомогательными, и используются при описании параметров методов класса Regex или их возвращаемых значений.
Класс Regex имеет конструктор, который принимает регулярное выражение:
Regex regex = new Regex(pattern);Здесь
pattern - строка, содержащая регулярное выражение. Описание класса со всеми вариантами конструктора.Для обработки строк с помощью регулярных выражений не обязательно создавать экземпляры класса Regex; вместо этого можно использовать статические методы данного класса.
Методы класса Regex
Все основные методы класса Regex реализованы в двух вариантах: статическом и экземплярном; при этом каждый из вариантов реализован для нескольких наборов параметров. Имеется шесть основных методов:IsMatch(типаbool) - возвращает True, если требуемое выражение найдено, и False в противном случае;Match(типаMatch) - возвращает первое найденное выражение;Matches(типаMatchCollection) - возвращает все найденные выражения;Split(типа string[]) - разбивает строку на фрагменты; разделители фрагментов определяются регулярным выражением;Replace(типаstring) - заменяет найденные выражения.
Проверка на соответствие сроки формату
Задача: определить, является ли заданная строка ростовским городским телефонным номером в федеральном формате (формат номера:+7 (863) 2**-**-** или +7 (863) 3**-**-**). Такая задача может быть решена в виде следующей функции:
static bool IsPhoneNo(string input)
{
Regex regex = new Regex(@"^\+7\s*\(863\)\s*[23]\d{2}-\d{2}-\d{2}$");
return regex.IsMatch(input);
}
или (если использовать статический метод)
static bool IsPhoneNo(string input) =>
Regex.IsMatch(input, @"^\+7\s*\(863\)\s*[23]\d{2}-\d{2}-\d{2}$");
Здесь перед началом строки регулярного выражения стоит символ «@» который указывает компилятору воспринимать все символы буквально. Это необходимо, чтобы корректно воспринимался символ «\».
Использование Match
Задача: найти в строке первое слово, которое начинается с буквы 'a'static string FirstWordStartingWithA(string input)
{
var match = Regex.Match(input, @"\ba\w*\b", RegexOptions.IgnoreCase);
return match.Value;
}
Метод Match возвращает значение класса Match. Value - свойство класса, которое соответствует найденной подстроке. Прочие свойства класса Match.
Поиск в строке всех вхождений регулярного выражения
Задача: Дана строка, содержащая слова, знаки пунктуации и числа в десятичной системе счисления. Сформировать последовательность строк, содержащий все строковые представления чисел из исходной строки в том же порядке.static IEnumerable<string> AllNumbers(string input) =>
Regex.Matches(input, @"\b\d+\b").Select(x => x.Value);
Метод Match возвращает значение класса MatchCollection. Элементы MatchCollection можно перебрать в цикле
var s = "red green gray blue";
foreach (Match m in Regex.Matches(s,@"\w+"))
WriteLine($"{m.Value} {m.Index}");
Разбиение строки на фрагменты
Задача: Дана строка, содержащая слова, разделённые одним или несколькими пробелами. Сформировать последовательность строк, содержащий все слова из исходной строки в том же порядке.static string[] WordsInString(string input)
=> Regex.Split(input, @"\s+");
Группирование и ссылки на группы
С помощью круглых скобок можно формировать группы регулярного выражения, на которые в дальнейшем можно ссылаться по номеру или по имени:(expr)- включить соответствие для выражения expr в нумерованную группу (группы нумеруются от 1 согласно порядку следования их открывающих скобок; группа 0 соответствует всему найденному вхождению);-
(?<name>expr)или(?'name'expr)- включить соответствие для выражения expr в именованную группу с именем name; -
(?:expr)- группирующее выражение, не связываемое с нумерованной или именованной группой; \N- ссылка на ранее найденную группу с номером N, означающая, что в данной позиции регулярного выражения должен содержаться текст этой группы;\k- ссылка на группу с именем nаme.
Задача: Написать функцию, которая по заданному телефонному номеру в федеральном формате (+7 (код_города) городской_номер) возвращает городской телефонный номер. Считать, что код города может состоять из трёх или четырёх цифр. Если исходная строка не соответствует заданному формату, возвращать пустую строку.
static string CityNum(string input) =>
Regex.Match(input, @"\+7\s*\(\d{3,4}\)\s*(\d{2,3}\-\d{2}\-\d{2})")
.Groups[1].Value;
Замены при помощи регулярных выражений
В выражениях замены используются управляющие последовательности (подстановки), отличные от директив языка регулярных выражений. Ниже приводятся наиболее часто используемые подстановки:
- $$ - символ $;
- $0 - все найденное вхождение;
- $_ - вся исходная строка;
- $N - найденная группа с номером N (или пустая строка, если группа не найдена);
- ${name} - найденная группа с именем name (или пустая строка, если группа не найдена).
var s = "Взять все слова в угловые скобки"; s = Regex.Replace(s,@"\b\w+\b", "<$0>"); Console.WriteLine(s);В случае сложных видов замены используется вариант метода Replace с параметром-делегатом MatchEvaluator.
var s = "Удвоить все числа в строке: 10+12=22"; s = Regex.Replace(s, @"\d+", m => (int.Parse(m.Value) * 2).ToString()); Console.WriteLine(s);
var s = "Изменить формат даты: 3/18/2019";
s = Regex.Replace(s, @"(\d{1,2})/(\d{1,2})/(\d{1,4})", @"$2.$1.$3" );
Console.WriteLine(s);