Классы библиотеки .NET для работы с регулярными выражениями
Класс ы библиотеки.NET для работы с регулярным и выражениями объединены в пространство имен System.Text.RegularExpressions. Начнем с класса Regex, представляющего собственно регулярное выражение. Класс является неизменяемым, то есть после создания экземпляра его корректировка не допускается. Для описания регулярного выражения в классе определено несколько перегруженных конструкторов: - Regex () — создает пустое выражение; - Regex(String) — создает заданное выражение; - Regex(String, RegexOptions) — создает заданное выражение и задает параметры для его обработки с помощью элементов перечисления RegexOptions (например, различать или не различать прописные и строчные буквы). Пример конструктора, задающего выражение для поиска в тексте повторяющихся слов, расположенных подряд и разделенных произвольным количеством пробелов, независимо от регистра: Regex гх = new Regex(@" \b(? < word> \w+)\s+(\1< word>)\b", RegexOptions.IgnoreCase); Поиск фрагментов строки, соответствующих заданному выражению, выполняется с помощью методов IsMatch, Match и Matches. Метод IsMatch возвращает true, если фрагмент, соответствующий выражению, в заданной строке найден, и false в противном случае. В листинге 3.1 приведен пример поиска повторяющихся слов в двух тестовых строках. В регулярное выражение, приведенное ранее, добавлен фрагмент, позволяющий распознавать знаки препинания. Листинг 3.1. Поиск в строке дублированных слов (методом IsMatch) using System; using System.Text.RegularExpressions; public class Test { public static void Main() { Regex r = new Regex(@" \b(? < word> \w+)[.,:;!? ]\s*(\k< word>)\b", RegexOptions.IgnoreCase); string tst1 = " Oh. oh! Good morning! "; if (r.IsMatch(tstl)) Console.WriteLine(" tstl yes"); else Console.WriteLine(" tstl no"); string tst2 = " Oh good morning. good morning, dear friend! "; if (r.IsMatch(tst2)) Console.WriteLine(" tst2 yes"); else Console.WriteLine(" tst2 no"); } } Результат работы программы: tstl yes tst2 no
Повторяющиеся слова в строке tst2 располагаются не подряд, поэтому она не соответствует регулярному выражению. Для поиска повторяющихся слов, расположенных в произвольных позициях строки, в регулярном выражении нужно всего-навсего заменить пробел (\s) «любым символом» (.): Regex г = new Regex(@a" \b(? < word> \w+)[..:;!? ].*(\1< word>)\b", RegexOptions.IgnoreCase); Метод Match класса Regex, в отличие от метода IsMatch, не просто определяет, произошло ли совпадение, а возвращает объект класса Match — очередной фрагмент, совпавший с образцом. Рассмотрим листинг 3.2, в котором используется этот метод. Листинг 3.2. Выделение из строки слов и чисел (методом Match) using System; using System.Text.RegularExpressions; public class Test { public static void Main() { string text = " Салат - $4, борщ - $3, одеколон - $10."; string pattern = @" (\w+) - \$(\d+)[., ]"; Regex r = new Regex(pattern); Match m = r.Match(text); int total = 0; while (m.Success) { Console.WriteLine(m); total += int.Parse(m.Groups[2].ToString()); m = m.NextMatch(); } Console.WriteLine(" Итого: $" + total); } } Результат работы программы: Салат - $4, борщ - $3, одеколон - $10. Итого: $17
При первом обращении к методу Match возвращается первый фрагмент строки, совпавший с регулярным выражением pattern. В классе Match определено свойство Groups, возвращающее коллекцию фрагментов, совпавших с подвыражениями в круглых скобках. Нулевой элемент коллекции содержит весь фрагмент, первый элемент — фрагмент, совпавший с подвыражением в первых скобках, второй элемент — фрагмент, совпавший с подвыражением во вторых скобках, и т. д. Если при определении выражения задать фрагментам имена, как это было сделано в предыдущем листинге, можно будет обратиться к ним по этим именам, например; string pattern = @" (? 'name'\w+) - \$(? 'price'\d+)[., ]"; total += int.Parse(m.Groups[" price" ].ToString()); Метод NextMatch класса Ma t ch продолжает поиск в строке с того места, на котором закончился предыдущий поиск. Метод Matches класса Regex возвращает объект класса MatchCollection - коллекцию всех фрагментов заданной строки, совпавших с образцом. Рассмотрим теперь пример применения метода Split класса Regex. Этот метод разбивает заданную строку на фрагменты в соответствии с разделителями, заданными с помощью регулярного выражения, и возвращает эти фрагменты в массиве строк. В листинге 3.3 строка из листинга 3.2 разбивается на отдельные слова. Листинг 3.3. Разбиение строки на слова (методом Split) using System; using System.Col1ections.Generiс; using System.Text.RegularExpressions; public class Test { public static void Main() { string text = " Салат - $4, борщ -$3. одеколон - $10."; string pattern = " [ - ]+"; Regex r = new Regex(pattern); List< string> words = new List< string> (r.Split(text)); foreach (string word in words) Console.WriteLine(word); } } Результат работы программы: Салат $4 борщ $3 одеколон $10
Метод Replасе класса Regex позволяет выполнять замену фрагментов текста. Определено несколько перегруженных версий этого метода. Вот как выглядит пример простейшего применения метода в его статическом варианте, заменяющего все вхождения символа $ символами у. е.: string text = " Салат - $4, борщ -$3, одеколон - $10."; string textl = Regex.Replасе(text, @" \$", " y.e."); Другие версии метода позволяют задавать любые действия по замене с помощью делегата MatchEvaluator, который вызывается для каждого вхождения фрагмента, совпавшего с заданным регулярным выражением. Помимо классов Regex и Match в пространстве имен System.Text.RegularExpressions определены вспомогательные классы, например, класс Capture - фрагмент, совпавший с подвыражением в круглых скобках; класс CaptureCollection — коллекция фрагментов, совпавших со всеми подвыражениями в текущей группе; класс Group содержит коллекцию Capture для текущего совпадения с регулярным выражением и т. д.
|