Страница 299 из 371
{n} ∙ Задает в точности n соответствий; например, w{2}
{n,} ∙ Задает, по меньшей мере, n соответствий; например, (abc) {2, }
{n,m} ∙ Задает, по меньшей мере, n, но не более m соответствий; например, (abc) {2,5}
Категория: Группирование
(?<Name>) ∙ При обнаружении соответствия выражению, заданному в круглых скобках, создается именованная группа, которой дается имя Name. Например, (?<tei> d{7}). При обнаружении последовательности из семи цифр будет создана группа с именем tel
() ∙ Круглые скобки разбивают регулярное выражение на группы. Для каждого подвыражения, заключенного в круглые скобки, создается группа, автоматически получающая номер. Номера следуют в обратном порядке, поэтому полному регулярному выражению соответствует группа с номером 0
(?imnsx) ∙ Включает или выключает в группе любую из пяти возможных опций. Для выключения опции перед ней ставится знак минус. Например, (?i-s:) включает опцию i, задающую нечувствительность к регистру, и выключает опцию s — статус single-line
Знакомство с классами пространства RegularExpressions
В данном пространстве расположено семейство из одного перечисления и восьми связанных между собой классов.
Класс Regex
Это основной класс, всегда создаваемый при работе с регулярными выражениями. Объекты этого класса определяют регулярные выражения. Конструктор класса, как обычно, перегружен. В простейшем варианте ему передается в качестве параметра строка, задающая регулярное выражение. В других вариантах конструктора ему может быть передан объект, принадлежащий перечислению RegexOptions и задающий опции, которые действуют при работе с данным объектом. Среди опций отмечу одну: ту, что позволяет компилировать регулярное выражение. В этом случае создается программа, которая и будет выполняться при каждом поиске соответствия. При разборе больших текстов скорость работы в этом случае существенно повышается.
Рассмотрим четыре основных метода класса Regex.
Метод Match запускает поиск соответствия. В качестве параметра методу передается строка поиска, где разыскивается первая подстрока, которая удовлетворяет образцу, заданному регулярным выражением. В качестве результата метод возвращает объект класса Match, описывающий результат поиска. При успешном поиске свойства объекта будут содержать информацию о найденной подстроке.
Метод Matches позволяет разыскать все вхождения, то есть все подстроки, удовлетворяющие образцу.
У алгоритма поиска есть важная особенность — разыскиваются непересекающиеся вхождения подстрок. Можно считать, что метод Matches многократно запускает метод Match, каждый раз начиная поиск с того места, на котором закончился предыдущий поиск. В качестве результата возвращается объект MatchCollection, представляющий коллекцию объектов Match.
Метод NextMatch запускает новый поиск, начиная с того места, на котором остановился предыдущий поиск.
Метод Split является обобщением метода Split класса String. Он позволяет, используя образец, разделить искомую строку на элементы. Поскольку образец может быть устроен сложнее, чем простое множество разделителей, то метод Split класса Regex эффективнее, чем его аналог класса string.
Классы Match и MatchCollection
Как уже говорилось, объекты этих классов создаются автоматически при вызове методов Match и Matches. Коллекция MatchCollection, как и все коллекции, позволяет получить доступ к каждому ее элементу — объекту Match. Можно, конечно, организовать цикл for each для последовательного доступа ко всем элементам коллекции.
Класс Match является непосредственным наследником класса Group, который, в свою очередь, является наследником класса Capture. При работе с объектами класса Match наибольший интерес представляют не столько методы класса, сколько его свойства, большая часть которых унаследована от родительских классов. Рассмотрим основные свойства:
• свойства Index, Length и Value наследованы от прародителя Capture. Они описывают найденную подстроку-индекс начала подстроки в искомой строке, длину подстроки и ее значение;
• свойство Groups класса Match возвращает коллекцию групп — объект GroupCollection, который позволяет работать с группами, созданными в процессе поиска соответствия;
• свойство Captures, наследованное от объекта Group, возвращает коллекцию CaptureCollection. Как видите, при работе с регулярными выражениями реально приходится создавать один объект класса Regex, объекты других классов автоматически появляются в процессе работы с объектами Regex.
Классы Group и GroupCollection
Коллекция GroupCollection возвращается при вызове свойства Group объекта Match. Имея эту коллекцию, можно добраться до каждого объекта Group, в нее входящего. Класс Group является наследником класса Capture и, одновременно, родителем класса Match. От своего родителя он наследует свойства Index, Length и Value, которые и передает своему потомку.
Давайте рассмотрим чуть более подробно, когда и как создаются группы в процессе поиска соответствия. Если внимательно проанализировать предыдущую таблицу, которая описывает символы, используемые в регулярных выражениях, в частности символы группирования, то можно понять несколько важных фактов, связанных с группами:
• при обнаружении одной подстроки, удовлетворяющей условию поиска, создается не одна группа, а коллекция групп;
• группа с индексом 0 содержит информацию о найденном соответствии;
• число групп в коллекции зависит от числа круглых скобок в записи регулярного выражения. Каждая пара круглых скобок создает дополнительную группу, которая описывает ту часть подстроки, которая соответствует шаблону, заданному в круглых скобках;
• группы могут быть индексированы, но могут быть и именованными, поскольку в круглых скобках разрешается указывать имя группы.
В заключение отмечу, что создание именованных групп крайне полезно при разборе строк, содержащих разнородную информацию. Примеры разбора подобных текстов будут даны.
Классы Capture и CaptureCollection
Коллекция CaptureCollection возвращается при вызове свойства Captures объектов класса Group и Match. Класс Match наследует это свойство у своего родителя — класса Group. Каждый объект Capture, входящий в коллекцию, характеризует соответствие, захваченное в процессе поиска, — соответствующую подстроку. Но поскольку свойства объекта Capture передаются по наследству его потомкам, то можно избежать непосредственной работы с объектами Capture. По крайней мере, в моих примерах не встретится работа с этим объектом, хотя "за кулисами" он непременно присутствует.
Перечисление RegexOptions
Объекты этого перечисления описывают опции, влияющие на то, как устанавливается соответствие. Обычно такой объект создается первым и передается конструктору объекта класса Regex. В вышеприведенной таблице, в разделе, посвященном символам группирования, говорится о том, что опции можно включать и выключать, распространяя, тем самым, их действие на участок шаблона, заданный соответствующей группой. Об одной из этих опций — Compiled, влияющей на эффективность работы регулярных выражений, уже упоминалось. Об остальных говорить не буду — при необходимости можно посмотреть справку.