Объектная модель регулярных выражений

В этом разделе приводится описание объектной модели, которая используется при работе с регулярными выражениями на платформе .NET Framework. Он содержит следующие подразделы:

  • Обработчик регулярных выражений

  • Классы MatchCollection и Match

  • Класс GroupCollection

  • Класс Group

  • Класс СaptureCollection

  • Класс Capture

Обработчик регулярных выражений

Обработчик регулярных выражений на платформе .NET Framework предоставляется классом Regex. Обработчик регулярных выражений отвечает за синтаксический разбор и компилирование регулярного выражения, а также для выполнения операций, которые сопоставляют шаблон регулярного выражения с входной строкой. Обработчик является центральным компонентом в объектной модели регулярных выражений платформы .NET Framework.

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

  • С помощью вызова статических методов класса Regex. Параметры метода содержат входную строку и шаблон регулярного выражения. Обработчик регулярных выражений кэширует регулярные выражения, которые используются в вызовах статических методов. В связи с этим повторяющиеся вызовы к статическим методам регулярных выражений, в которых используются одинаковые регулярные выражения, характеризуются относительно хорошей производительностью.

  • С помощью создания объекта Regex, посредством передачи регулярного выражения в конструктор класса. В данном случае объект класса Regex является неизменяемым (доступен только для чтения) и представляет обработчик регулярного выражения, который тесно связан с одним регулярным выражением. Так как регулярные выражения, которые используются экземплярами класса Regex, не кэшируются, не следует создавать объект класса Regex несколько раз с одним регулярным выражением.

Методы класса Regex можно вызвать для выполнения следующих действий.

  • Определение, соответствует ли строка шаблону регулярного выражения.

  • Извлечение одного совпадения или первого совпадения.

  • Извлечение всех совпадений.

  • Замена сопоставленной подстроки.

  • Разделение одной строки на массив строк.

Эти операции описаны в следующих подразделах.

Сопоставление шаблона регулярного выражения

Метод Regex.IsMatch возвращает значение true, если строка сопоставлена шаблону, в противном случае — значение false. Метод IsMatch часто используется для проверки входной строки. Например, следующий пример кода гарантирует, что строка сопоставлена с правильным номером карточки социального страхования (США).

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim values() As String = { "111-22-3333", "111-2-3333"}
      Dim pattern As String = "^\d{3}-\d{2}-\d{4}$"
      For Each value As String In values
         If Regex.IsMatch(value, pattern) Then
            Console.WriteLine("{0} is a valid SSN.", value)
         Else   
            Console.WriteLine("{0}: Invalid", value)
         End If   
      Next
   End Sub
End Module
' The example displays the following output:
'       111-22-3333 is a valid SSN.
'       111-2-3333: Invalid
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string[] values = { "111-22-3333", "111-2-3333"};
      string pattern = @"^\d{3}-\d{2}-\d{4}$";
      foreach (string value in values) {
         if (Regex.IsMatch(value, pattern))
            Console.WriteLine("{0} is a valid SSN.", value);
         else   
            Console.WriteLine("{0}: Invalid", value);
      }
   }
}
// The example displays the following output:
//       111-22-3333 is a valid SSN.
//       111-2-3333: Invalid

Интерпретация шаблона регулярного выражения ^\d{3}-\d{2}-\d{4}$ показана в следующей таблице.

Шаблон

Описание

^

Соответствует началу входной строки.

\d{3}

Совпадение с тремя десятичными цифрами.

-

Совпадение со знаком дефиса.

\d{2}

Совпадение с двумя десятичными цифрами.

-

Совпадение со знаком дефиса.

\d{4}

Совпадение с четырьмя десятичными цифрами.

$

Соответствует концу входной строки.

Извлечение одного совпадения или первого совпадения

Метод Regex.Match возвращает объект класса Match который содержит сведения о первой подстроке, которая сопоставлена шаблону регулярного выражения. Если свойство Match.Success возвращает значение true, означающее, что было найдено совпадение, то сведения о следующих совпадениях можно получить с помощью вызова метода Match.NextMatch. Эти вызовы метода можно продолжать пока свойство Match.Success не вернет значение false. Например, в следующем примере кода метод Regex.Match(String, String) используется для поиска первого вхождения дублированного слова в строке. Затем он вызывает метод Match.NextMatch для поиска всех оставшихся вхождений. В этом примере после каждого вызова метода выполняется проверка свойства Match.Success для определения было ли текущее совпадение успешным и нужно ли далее вызывать метод Match.NextMatch.

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim input As String = "This is a a farm that that raises dairy cattle." 
      Dim pattern As String = "\b(\w+)\W+(\1)\b"
      Dim match As Match = Regex.Match(input, pattern)
      Do While match.Success
         Console.WriteLine("Duplicate '{0}' found at position {1}.", _ 
                           match.Groups(1).Value, match.Groups(2).Index)
         match = match.NextMatch()
      Loop                       
   End Sub
End Module
' The example displays the following output:
'       Duplicate 'a' found at position 10.
'       Duplicate 'that' found at position 22.
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string input = "This is a a farm that that raises dairy cattle."; 
      string pattern = @"\b(\w+)\W+(\1)\b";
      Match match = Regex.Match(input, pattern);
      while (match.Success)
      {
         Console.WriteLine("Duplicate '{0}' found at position {1}.",  
                           match.Groups[1].Value, match.Groups[2].Index);
         match = match.NextMatch();
      }                       
   }
}
// The example displays the following output:
//       Duplicate 'a' found at position 10.
//       Duplicate 'that' found at position 22.

Интерпретация шаблона регулярного выражения \b(\w+)\W+(\1)\b показана в следующей таблице.

Шаблон

Описание

\b

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

(\w+)

Совпадение с одним или несколькими символами слова. Это первая группа записи.

\W+

Совпадение с одним или несколькими символами, которые не являются буквой.

(\1)

Соответствует первой записанной строке. Это вторая группа записи.

\b

Совпадение должно заканчиваться на границе слова.

Извлечение всех совпадений

Метод Regex.Matches возвращает объект класса MatchCollection, который содержит сведения обо всех совпадениях, которые обработчик регулярных выражений находит во входной строке. Например, предыдущий пример может быть переписан для вызова метода Matches вместо метода Match и метода NextMatch.

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim input As String = "This is a a farm that that raises dairy cattle." 
      Dim pattern As String = "\b(\w+)\W+(\1)\b"
      For Each match As Match In Regex.Matches(input, pattern)
         Console.WriteLine("Duplicate '{0}' found at position {1}.", _ 
                           match.Groups(1).Value, match.Groups(2).Index)
      Next                       
   End Sub
End Module
' The example displays the following output:
'       Duplicate 'a' found at position 10.
'       Duplicate 'that' found at position 22.
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string input = "This is a a farm that that raises dairy cattle."; 
      string pattern = @"\b(\w+)\W+(\1)\b";
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("Duplicate '{0}' found at position {1}.",  
                           match.Groups[1].Value, match.Groups[2].Index);
   }
}
// The example displays the following output:
//       Duplicate 'a' found at position 10.
//       Duplicate 'that' found at position 22.

Замена сопоставленной подстроки

Метод Regex.Replace заменяет каждую подстроку, которая сопоставлена шаблону регулярного выражения на заданную строку или шаблоном регулярного выражения, и возвращает всю входную строку вместе с изменениями. Например, следующий код добавляет символ валюты США перед десятичной цифрой в строке.

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern As String = "\b\d+\.\d{2}\b"
      Dim replacement As String = "$$$&" 
      Dim input As String = "Total Cost: 103.64"
      Console.WriteLine(Regex.Replace(input, pattern, replacement))     
   End Sub
End Module
' The example displays the following output:
'       Total Cost: $103.64
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b\d+\.\d{2}\b";
      string replacement = "$$$&"; 
      string input = "Total Cost: 103.64";
      Console.WriteLine(Regex.Replace(input, pattern, replacement));     
   }
}
// The example displays the following output:
//       Total Cost: $103.64

Интерпретация шаблона регулярного выражения \b\d+\.\d{2}\b показана в следующей таблице.

Шаблон

Описание

\b

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

\d+

Совпадение с одной или несколькими десятичными цифрами.

\.

Совпадение с точкой.

\d{2}

Совпадение с двумя десятичными цифрами.

\b

Совпадение должно заканчиваться на границе слова.

Интерпретация шаблона замены $$$& показана в следующей таблице.

Шаблон

Строка замены

$$

Символ знака доллара ($).

$&

Вся сопоставленная подстрока.

Разделение одной строки на массив строк

Метод Regex.Split разделяет входную строку в позициях, которые определяются сопоставлением регулярного выражения. Например, следующий код помещает элементы нумерованного списка в массив строк.

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim input As String = "1. Eggs 2. Bread 3. Milk 4. Coffee 5. Tea"
      Dim pattern As String = "\b\d{1,2}\.\s"
      For Each item As String In Regex.Split(input, pattern)
         If Not String.IsNullOrEmpty(item) Then
            Console.WriteLine(item)
         End If
      Next      
   End Sub
End Module
' The example displays the following output:
'       Eggs
'       Bread
'       Milk
'       Coffee
'       Tea
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string input = "1. Eggs 2. Bread 3. Milk 4. Coffee 5. Tea";
      string pattern = @"\b\d{1,2}\.\s";
      foreach (string item in Regex.Split(input, pattern))
      {
         if (! String.IsNullOrEmpty(item))
            Console.WriteLine(item);
      }      
   }
}
// The example displays the following output:
//       Eggs
//       Bread
//       Milk
//       Coffee
//       Tea

Интерпретация шаблона регулярного выражения \b\d{1,2}\.\s показана в следующей таблице.

Шаблон

Описание

\b

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

\d{1,2}

Совпадение с одной или двумя десятичными цифрами.

\.

Совпадение с точкой.

\s

Совпадение с символом пробела.

Классы MatchCollection и Match

Метод Regex возвращает два объекта, которые являются частью объектной модели регулярных выражений — объект класса MatchCollection и объект класса Match.

Класс MatchCollection

Метод Regex.Matches возвращает объект MatchCollection, содержащий объекты класса Match, которые представляют все совпадения, которые нашел обработчик регулярных выражений, в том порядке, в каком они находятся во входной строке. Если совпадений не найдено, метод возвращает объект класса MatchCollection, который не содержит элементов. Свойство MatchCollection.Item позволяет выполнять доступ к отдельным элементам коллекции по индексу, от нуля до на меньшего на единицу значения свойства MatchCollection.Count. Свойство Item является индексатором коллекции (в C#) и свойством по умолчанию (в Visual Basic).

По умолчанию вызов метода Regex.Matches использует отложенное вычисление для заполнения объекта MatchCollection. Доступ к свойствам, которые требуют полностью заполненной коллекции, например к свойствам MatchCollection.Count и MatchCollection.Item может вызвать снижение производительности. В результате рекомендуется, чтобы доступ к коллекции выполнялся с помощью объекта IEnumerator, который возвращается методом MatchCollection.GetEnumerator. Отдельные языки предоставляют конструкции, например, For Each в Visual Basic и foreach в C#, которые служат оболочкой интерфейса IEnumerator у коллекции.

В следующем примере метод Regex.Matches(String) используется для заполнения объекта класса MatchCollection всеми совпадениями, которые были найдены во входной строке. В этом примере кода выполняется перечисление коллекции, копирование совпадений в массив строк, запись позиций символов в массив целых чисел.

Imports System.Collections.Generic
Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
       Dim matches As MatchCollection
       Dim results As New List(Of String)
       Dim matchposition As New List(Of Integer)

       ' Create a new Regex object and define the regular expression.
       Dim r As New Regex("abc")
       ' Use the Matches method to find all matches in the input string.
       matches = r.Matches("123abc4abcd")
       ' Enumerate the collection to retrieve all matches and positions.
       For Each match As Match In matches
          ' Add the match string to the string array.
           results.Add(match.Value)
           ' Record the character position where the match was found.
           matchposition.Add(match.Index)
       Next
       ' List the results.
       For ctr As Integer = 0 To results.Count - 1
         Console.WriteLine("'{0}' found at position {1}.", _
                           results(ctr), matchposition(ctr))  
       Next
   End Sub
End Module
' The example displays the following output:
'       'abc' found at position 3.
'       'abc' found at position 7.
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
       MatchCollection matches;
       List<string> results = new List<string>();
       List<int> matchposition = new List<int>();

       // Create a new Regex object and define the regular expression.
       Regex r = new Regex("abc");
       // Use the Matches method to find all matches in the input string.
       matches = r.Matches("123abc4abcd");
       // Enumerate the collection to retrieve all matches and positions.
       foreach (Match match in matches)
       {
          // Add the match string to the string array.
           results.Add(match.Value);
           // Record the character position where the match was found.
           matchposition.Add(match.Index);
       }
       // List the results.
       for (int ctr = 0; ctr < results.Count; ctr++)
         Console.WriteLine("'{0}' found at position {1}.", 
                           results[ctr], matchposition[ctr]);  
   }
}
// The example displays the following output:
//       'abc' found at position 3.
//       'abc' found at position 7.

Класс Match

Класс Match представляет результат одного совпадения регулярного выражения. Доступ к объекту класса Match можно выполнить двумя способами.

  • С помощью его извлечения из объекта класса MatchCollection, который возвращается методом Regex.Matches. Для получения отдельных объектов Match выполните итерацию коллекции с помощью конструкций foreach (в C#) или For Each...Next (в Visual Basic). Либо используйте свойство MatchCollection.Item для получения определенного объекта Match по индексу или по имени. Также можно извлечь отдельные объекты Match из коллекции с помощью итерации коллекции по индексу от нуля до значения, на единицу меньшего числа объектов в коллекции. Однако этот метод не дает воспользоваться преимуществами отложенного вычисления, так как он выполняет доступ к свойству MatchCollection.Count.

    Следующий пример получает отдельные объекты класса Match из объекта класса MatchCollection с помощью итерации коллекции с использованием конструкции foreach или конструкции For Each...Next. Регулярное выражение просто находит совпадения со строкой "abc" во входной строке.

    Imports System.Text.RegularExpressions
    
    Module Example
       Public Sub Main()
          Dim pattern As String = "abc"
          Dim input As String = "abc123abc456abc789"
          For Each match As Match In Regex.Matches(input, pattern)
             Console.WriteLine("{0} found at position {1}.", _
                               match.Value, match.Index)
          Next                     
       End Sub
    End Module
    ' The example displays the following output:
    '       abc found at position 0.
    '       abc found at position 6.
    '       abc found at position 12.
    
    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
       public static void Main()
       {
          string pattern = "abc";
          string input = "abc123abc456abc789";
          foreach (Match match in Regex.Matches(input, pattern))
             Console.WriteLine("{0} found at position {1}.", 
                               match.Value, match.Index);
       }
    }
    // The example displays the following output:
    //       abc found at position 0.
    //       abc found at position 6.
    //       abc found at position 12.
    
  • С помощью вызова метода Regex.Match, возвращающего объект класса Match, который представляет первое совпадение в строке или части строки. Чтобы определить было ли найдено совпадение, можно получить значение свойства Match.Success. Для получения объектов Match, которые представляют следующие совпадения, вызывайте повторно метод Match.NextMatch, пока свойство Success возвращаемого объекта Match не примет значение false.

    В следующем примере метод Regex.Match(String, String) и метод Match.NextMatch используются для поиска совпадения строки "abc" во входной строке.

    Imports System.Text.RegularExpressions
    
    Module Example
       Public Sub Main()
          Dim pattern As String = "abc"
          Dim input As String = "abc123abc456abc789"
          Dim match As Match = Regex.Match(input, pattern)
          Do While match.Success
             Console.WriteLine("{0} found at position {1}.", _
                               match.Value, match.Index)
             match = match.NextMatch()                  
          Loop                     
       End Sub
    End Module
    ' The example displays the following output:
    '       abc found at position 0.
    '       abc found at position 6.
    '       abc found at position 12.
    
    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
       public static void Main()
       {
          string pattern = "abc";
          string input = "abc123abc456abc789";
          Match match = Regex.Match(input, pattern);
          while (match.Success)
          {
             Console.WriteLine("{0} found at position {1}.", 
                               match.Value, match.Index);
             match = match.NextMatch();                  
          }                     
       }
    }
    // The example displays the following output:
    //       abc found at position 0.
    //       abc found at position 6.
    //       abc found at position 12.
    

Два свойства класса Match возвращают объекты коллекции.

  • Свойство Match.Groups возвращает объект GroupCollection, который содержит сведения о подстроках, которые сопоставлены группам записи в шаблоне регулярного выражения.

  • Свойство Group.Captures возвращает объект класса CaptureCollection, что зачастую малополезно. Коллекция не заполняется для объекта Match, у которого свойство Success имеет значение false. В противном случае он содержит один объект Capture, который содержит такую же информацию, как объект Match.

Дополнительные сведения об этих объектах см. в подразделах Класс GroupCollection и Класс СaptureCollection ранее в данном разделе.

Два дополнительных свойства класса Match предоставляют сведения о совпадении. Свойство Match.Value возвращает подстроку во входной строке, которая совпадает с шаблоном регулярного выражения. Свойство Match.Index возвращает начальную позицию, которая ведется от нуля, совпавшей строки во входной строке.

Класс Match также содержит два метода сопоставления шаблонов.

  • Метод Match.NextMatch находит следующее совпадение после совпадения, которое представляется текущим объектом Match, и возвращает объект Match, который представляет это совпадение.

  • Метод Match.Result выполняет заданную операцию замены в совпавшей строке и возвращает результат.

Следующий пример использует метод Match.Result для вставки в начале символа $ и пробела между каждым числом, которое содержит две цифры дробной части.

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern As String = "\b\d+(,\d{3})*\.\d{2}\b"
      Dim input As String = "16.32" + vbCrLf + "194.03" + vbCrLf + "1,903,672.08" 

      For Each match As Match In Regex.Matches(input, pattern)
         Console.WriteLine(match.Result("$$ $&"))
      Next
   End Sub
End Module
' The example displays the following output:
'       $ 16.32
'       $ 194.03
'       $ 1,903,672.08
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b\d+(,\d{3})*\.\d{2}\b";
      string input = "16.32\n194.03\n1,903,672.08"; 

      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine(match.Result("$$ $&"));
   }
}
// The example displays the following output:
//       $ 16.32
//       $ 194.03
//       $ 1,903,672.08

Шаблон регулярного выражения \b\d+(,\d{3})*\.\d{2}\b определяется, как показано в следующей таблице.

Шаблон

Описание

\b

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

\d+

Совпадение с одной или несколькими десятичными цифрами.

(,\d{3})*

Совпадение с запятой, за которой следуют три десятичные цифры.

\.

Совпадение с символом десятичной точки.

\d{2}

Совпадение с двумя десятичными цифрами.

\b

Совпадение должно заканчиваться на границе слова.

Шаблон замены $$ $& указывает, что совпавшая строка должна заменяться символом доллара ($) (шаблон $$), пробелом, и значением совпадения (шаблон $&).

К началу

Класс GroupCollection

Свойство Match.Groups возвращает объект класса GroupCollection, содержащий объекты класса Group, которые представляют записанные группы в одном совпадении. Первый объект Group в коллекции (с индексом 0) представляет все совпадение. Каждый следующий объект представляет результаты из одной группы записи.

Отдельные объекты класса Group в коллекции можно получить с помощью свойства GroupCollection.Item. Можно получить группы без имени по их порядковому номеру в коллекции. Можно получить именованные группы по имени и по порядковому номеру. Безымянные записи появляются в коллекции первыми. Они проиндексированы слева направо в порядке их появления в шаблоне регулярного выражения. Именованные записи проиндексированы после безымянных записей, слева направо в порядке их появления в шаблоне регулярного выражения.

Свойство GroupCollection.Item является индексатором в коллекции в C# и свойством по умолчанию объекта коллекции в Visual Basic. Это значит, что доступ к отдельным объектам класса Group может быть выполнен по индексу (или в случае именованных групп по имени) следующим образом.

Dim group As Group = match.Groups(ctr)         
Group group = match.Groups[ctr];         

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

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern As String = "\b(\w+)\s(\d{1,2}),\s(\d{4})\b"
      Dim input As String = "Born: July 28, 1989"
      Dim match As Match = Regex.Match(input, pattern)
      If match.Success Then
         For ctr As Integer = 0 To match.Groups.Count - 1
            Console.WriteLine("Group {0}: {1}", ctr, match.Groups(ctr).Value)
         Next      
      End If   
   End Sub
End Module
' The example displays the following output:
'       Group 0: July 28, 1989
'       Group 1: July
'       Group 2: 28
'       Group 3: 1989
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(\w+)\s(\d{1,2}),\s(\d{4})\b";
      string input = "Born: July 28, 1989";
      Match match = Regex.Match(input, pattern);
      if (match.Success)
         for (int ctr = 0; ctr <  match.Groups.Count; ctr++)
            Console.WriteLine("Group {0}: {1}", ctr, match.Groups[ctr].Value);
    }
}
// The example displays the following output:
//       Group 0: July 28, 1989
//       Group 1: July
//       Group 2: 28
//       Group 3: 1989

Шаблон регулярного выражения \b(\w+)\s(\d{1,2}),\s(\d{4})\b определяется, как показано в следующей таблице.

Шаблон

Описание

\b

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

(\w+)

Совпадение с одним или несколькими символами слова. Это первая группа записи.

\s

Совпадение с символом пробела.

(\d{1,2})

Совпадение с одной или двумя десятичными цифрами. Это вторая группа записи.

,

Совпадение с запятой.

\s

Совпадение с символом пробела.

(\d{4})

Совпадение с четырьмя десятичными цифрами. Это третья группа записи.

\b

Совпадение должно заканчиваться на границе слова.

К началу

Класс Group

Класс Group представляет результат из отдельной группы записи. Группы объектов, которые представляют группы записи, определенные в регулярном выражении, возвращаются с помощью свойства Item объекта класса GroupCollection, который возвращается свойством Match.Groups. Свойство Item является индексатором (в C#) и свойством по умолчанию (в Visual Basic)класса Group. Отдельные элементы можно получить с помощью итерации коллекции с использованием конструкции foreach или конструкции For Each. См. пример в предыдущем подразделе.

В следующем примере кода используются вложенные конструкции группирования для записи подстрок в группы. Шаблон регулярного выражения (a(b))c находит совпадения со строкой "abc". Он назначает подстроку "ab" первой группе записи, подстроку "b" второй группе записи.

 Dim matchposition As New List(Of Integer)
 Dim results As New List(Of String)
 ' Define substrings abc, ab, b.
 Dim r As New Regex("(a(b))c") 
 Dim m As Match = r.Match("abdabc")
 Dim i As Integer = 0
 While Not (m.Groups(i).Value = "")    
    ' Add groups to string array.
    results.Add(m.Groups(i).Value)     
    ' Record character position. 
    matchposition.Add(m.Groups(i).Index) 
     i += 1
 End While

 ' Display the capture groups.
 For ctr As Integer = 0 to results.Count - 1
    Console.WriteLine("{0} at position {1}", _ 
                      results(ctr), matchposition(ctr))
 Next                     
' The example displays the following output:
'       abc at position 3
'       ab at position 3
'       b at position 4
List<int> matchposition = new List<int>();
List<string> results = new List<string>();
// Define substrings abc, ab, b.
Regex r = new Regex("(a(b))c"); 
Match m = r.Match("abdabc");
for (int i = 0; m.Groups[i].Value != ""; i++) 
{
   // Add groups to string array.
   results.Add(m.Groups[i].Value); 
   // Record character position.
   matchposition.Add(m.Groups[i].Index); 
}

// Display the capture groups.
for (int ctr = 0; ctr < results.Count; ctr++)
   Console.WriteLine("{0} at position {1}", 
                     results[ctr], matchposition[ctr]);
// The example displays the following output:
//       abc at position 3
//       ab at position 3
//       b at position 4

В следующем примере кода используются именованные конструкции группирования для записи подстрок из строки, которая содержит данные в формате "DATANAME:VALUE", которую регулярное выражение разделяет в месте двоеточия (:).

Dim r As New Regex("^(?<name>\w+):(?<value>\w+)")
Dim m As Match = r.Match("Section1:119900")
Console.WriteLine(m.Groups("name").Value)
Console.WriteLine(m.Groups("value").Value)
' The example displays the following output:
'       Section1
'       119900
Regex r = new Regex("^(?<name>\\w+):(?<value>\\w+)");
Match m = r.Match("Section1:119900");
Console.WriteLine(m.Groups["name"].Value);
Console.WriteLine(m.Groups["value"].Value);
// The example displays the following output:
//       Section1
//       119900

Шаблон регулярного выражения ^(?<name>\w+):(?<value>\w+) определяется, как показано в следующей таблице.

Шаблон

Описание

^

Начало совпадения в начале входной строки.

(?<name>\w+)

Совпадение с одним или несколькими символами слова. Эта группа записи носит имя name.

:

Совпадение с двоеточием.

(?<value>\w+)

Совпадение с одним или несколькими символами слова. Эта группа записи носит имя value.

Свойство класса Group предоставляет сведения о записанной группе — свойство Group.Value содержит записанную подстроку, свойство Group.Index указывает начальную позицию записанной группы, свойство Group.Length содержит Group.Success указывает совпадает ли подстрока с шаблоном, который задается группой записи.

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

  • Если квантор * или *? (который задает нуль или несколько совпадений) применяется к группе, группа записи может не содержать совпадения во входной строке. Когда записанный текст отсутствует, свойства объекта Group устанавливаются так, как показано в таблице ниже.

    Свойство объекта класса Group

    Значение

    Success

    false

    Value

    String.Empty

    Length

    0

    Ниже приведен пример. В шаблоне регулярного выражения aaa(bbb)*ccc, первая группа записи (подстрока "bbb") может быть сопоставлена нуль или несколько раз. Так как строка ввода "aaaccc" совпадает с шаблоном, группа записи не содержит совпадения.

    Imports System.Text.RegularExpressions
    
    Module Example
       Public Sub Main()
          Dim pattern As String = "aaa(bbb)*ccc"
          Dim input As String = "aaaccc"
          Dim match As Match = Regex.Match(input, pattern)
          Console.WriteLine("Match value: {0}", match.Value)
          If match.Groups(1).Success Then
             Console.WriteLine("Group 1 value: {0}", match.Groups(1).Value)
          Else
             Console.WriteLine("The first capturing group has no match.")
         End If   
       End Sub
    End Module
    ' The example displays the following output:
    '       Match value: aaaccc
    '       The first capturing group has no match.
    
    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
       public static void Main()
       {
          string pattern = "aaa(bbb)*ccc";
          string input = "aaaccc";
          Match match = Regex.Match(input, pattern);
          Console.WriteLine("Match value: {0}", match.Value);
          if (match.Groups[1].Success)
             Console.WriteLine("Group 1 value: {0}", match.Groups[1].Value);
          else
             Console.WriteLine("The first capturing group has no match.");
       }
    }
    // The example displays the following output:
    //       Match value: aaaccc
    //       The first capturing group has no match.
    
  • Кванторы могут сопоставлять несколько вхождений шаблона, который определяется группой записи. В этом случае свойства Value и Length объекта класса Group содержат только сведения о последней записанной подстроке. Например, следующее регулярное выражение сопоставлено одному предложению, которое заканчивается точкой. В нем используется две конструкции группирования — первая записывает отдельные слова вместе с символами пробела, вторая записывает отдельные слова. Как видно из выходных данных в примере, хотя регулярное выражение успешно, в записи всего предложения, вторая группа записи записывает только последнее слово.

    Imports System.Text.RegularExpressions
    
    Module Example
       Public Sub Main()
          Dim pattern As String = "\b((\w+)\s?)+\."
          Dim input As String = "This is a sentence. This is another sentence."
          Dim match As Match = Regex.Match(input, pattern)
          If match.Success Then
             Console.WriteLine("Match: " + match.Value)
             Console.WriteLine("Group 2: " + match.Groups(2).Value)
          End If   
       End Sub
    End Module
    ' The example displays the following output:
    '       Match: This is a sentence.
    '       Group 2: sentence
    
    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
       public static void Main()
       {
          string pattern = @"\b((\w+)\s?)+\.";
          string input = "This is a sentence. This is another sentence.";
          Match match = Regex.Match(input, pattern);
          if (match.Success)
          {
             Console.WriteLine("Match: " + match.Value);
             Console.WriteLine("Group 2: " + match.Groups[2].Value);
          }   
       }
    }
    // The example displays the following output:
    //       Match: This is a sentence.
    //       Group 2: sentence
    

К началу

Класс СaptureCollection

Объект класса Group содержит сведения только о последней записи. Однако полный набор записей, которые сделаны группой записи по-прежнему доступен в объекте класса CaptureCollection, который возвращается свойством Group.Captures. Каждый элемент коллекции является объектом класса Capture, который представляет запись, сделанную этой группой записи. Элементы коллекции расположены в порядке их записи, поэтому этот порядок соответствует порядку, в котором записанные строки были сопоставлены во входной строке слева направо. Отдельные объекты Capture из коллекции можно получить двумя способами.

  • С помощью итерации коллекции с использованием такой конструкции, как foreach (в C#) или конструкции For Each (в Visual Basic).

  • С помощью использования свойства CaptureCollection.Item для получения определенного объекта по индексу. Свойство Item является свойством объекта CaptureCollection по умолчанию (в Visual Basic) или индексатором (в C#).

Если квантор не применяется к группе записи, объект класса CaptureCollection содержит один объект класса Capture, который не представляет особого интереса, так как он предоставляет сведения о том же совпадении, что объект класса Group. Если квантор применяется к группе записи, объект класса CaptureCollection содержит все записи, которые сделаны группой записи, а последний элемент коллекции представляет такую же запись, как объект класса Group.

Например, если используется шаблон регулярного выражения ((a(b))c)+ (в котором квантор + задает одно или несколько совпадений) для записи совпадений из строки "abcabcabc", объект класса CaptureCollection для каждого объекта класса Group содержит три элемента.

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern As String = "((a(b))c)+"
      Dim input As STring = "abcabcabc"

      Dim match As Match = Regex.Match(input, pattern)
      If match.Success Then
         Console.WriteLine("Match: '{0}' at position {1}", _ 
                           match.Value, match.Index)
         Dim groups As GroupCollection = match.Groups
         For ctr As Integer = 0 To groups.Count - 1
            Console.WriteLine("   Group {0}: '{1}' at position {2}", _
                              ctr, groups(ctr).Value, groups(ctr).Index)
            Dim captures As CaptureCollection = groups(ctr).Captures
            For ctr2 As Integer = 0 To captures.Count - 1
               Console.WriteLine("      Capture {0}: '{1}' at position {2}", _
                                 ctr2, captures(ctr2).Value, captures(ctr2).Index)
            Next
         Next
      End If
   End Sub
End Module
' The example dosplays the following output:
'       Match: 'abcabcabc' at position 0
'          Group 0: 'abcabcabc' at position 0
'             Capture 0: 'abcabcabc' at position 0
'          Group 1: 'abc' at position 6
'             Capture 0: 'abc' at position 0
'             Capture 1: 'abc' at position 3
'             Capture 2: 'abc' at position 6
'          Group 2: 'ab' at position 6
'             Capture 0: 'ab' at position 0
'             Capture 1: 'ab' at position 3
'             Capture 2: 'ab' at position 6
'          Group 3: 'b' at position 7
'             Capture 0: 'b' at position 1
'             Capture 1: 'b' at position 4
'             Capture 2: 'b' at position 7
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = "((a(b))c)+";
      string input = "abcabcabc";

      Match match = Regex.Match(input, pattern);
      if (match.Success)
      {
         Console.WriteLine("Match: '{0}' at position {1}",  
                           match.Value, match.Index);
         GroupCollection groups = match.Groups;
         for (int ctr = 0; ctr < groups.Count; ctr++) {
            Console.WriteLine("   Group {0}: '{1}' at position {2}", 
                              ctr, groups[ctr].Value, groups[ctr].Index);
            CaptureCollection captures = groups[ctr].Captures;
            for (int ctr2 = 0; ctr2 < captures.Count; ctr2++) {
               Console.WriteLine("      Capture {0}: '{1}' at position {2}", 
                                 ctr2, captures[ctr2].Value, captures[ctr2].Index);
            }                     
         }
      }
   }
}
// The example displays the following output:
//       Match: 'abcabcabc' at position 0
//          Group 0: 'abcabcabc' at position 0
//             Capture 0: 'abcabcabc' at position 0
//          Group 1: 'abc' at position 6
//             Capture 0: 'abc' at position 0
//             Capture 1: 'abc' at position 3
//             Capture 2: 'abc' at position 6
//          Group 2: 'ab' at position 6
//             Capture 0: 'ab' at position 0
//             Capture 1: 'ab' at position 3
//             Capture 2: 'ab' at position 6
//          Group 3: 'b' at position 7
//             Capture 0: 'b' at position 1
//             Capture 1: 'b' at position 4
//             Capture 2: 'b' at position 7

В следующем примере регулярное выражение (Abc)+ используется для поиска одного или нескольких последовательных вхождений "Abc" в строке "XYZAbcAbcAbcXYZAbcAb". В данном примере показано применение свойства Group.Captures для возврата нескольких групп записанных подстрок.

Dim counter As Integer
Dim m As Match
Dim cc As CaptureCollection
Dim gc As GroupCollection

' Look for groupings of "Abc".
Dim r As New Regex("(Abc)+") 
' Define the string to search.
m = r.Match("XYZAbcAbcAbcXYZAbcAb")
gc = m.Groups

' Display the number of groups.
Console.WriteLine("Captured groups = " & gc.Count.ToString())

' Loop through each group.
Dim i, ii As Integer
For i = 0 To gc.Count - 1
    cc = gc(i).Captures
    counter = cc.Count

    ' Display the number of captures in this group.
    Console.WriteLine("Captures count = " & counter.ToString())

    ' Loop through each capture in the group.            
    For ii = 0 To counter - 1
        ' Display the capture and its position.
        Console.WriteLine(cc(ii).ToString() _
            & "   Starts at character " & cc(ii).Index.ToString())
    Next ii
Next i
' The example displays the following output:
'       Captured groups = 2
'       Captures count = 1
'       AbcAbcAbc   Starts at character 3
'       Captures count = 3
'       Abc   Starts at character 3
'       Abc   Starts at character 6
'       Abc   Starts at character 9  
   int counter;
   Match m;
   CaptureCollection cc;
   GroupCollection gc;

   // Look for groupings of "Abc".
   Regex r = new Regex("(Abc)+"); 
   // Define the string to search.
   m = r.Match("XYZAbcAbcAbcXYZAbcAb"); 
   gc = m.Groups;

   // Display the number of groups.
   Console.WriteLine("Captured groups = " + gc.Count.ToString());

   // Loop through each group.
   for (int i=0; i < gc.Count; i++) 
   {
      cc = gc[i].Captures;
      counter = cc.Count;

      // Display the number of captures in this group.
      Console.WriteLine("Captures count = " + counter.ToString());

      // Loop through each capture in the group.
      for (int ii = 0; ii < counter; ii++) 
      {
         // Display the capture and its position.
         Console.WriteLine(cc[ii] + "   Starts at character " + 
              cc[ii].Index);
      }
   }
}
// The example displays the following output:
//       Captured groups = 2
//       Captures count = 1
//       AbcAbcAbc   Starts at character 3
//       Captures count = 3
//       Abc   Starts at character 3
//       Abc   Starts at character 6
//       Abc   Starts at character 9  

К началу

Класс Capture

Класс Capture содержит результаты выделения отдельного подвыражения. Свойство Capture.Value содержит сопоставленный текст, а свойство Capture.Index указывает позицию (с нуля) во входной строке, в которой начинается текст сопоставленной подстроки.

В следующем примере анализируется входная строка для температуры выбранных городов. Запятая (",") используется для разделения городов и температуры в них. Точка с запятой (";") используется для разделения данных по каждому городу. Вся входная строка представляет одно совпадение. В шаблоне регулярного выражения ((\w+(\s\w+)*),(\d+);)+, которое используется для анализа строки, названия городов назначены во вторую группу записи, температура назначена в четвертую группу записи.

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim input As String = "Miami,78;Chicago,62;New York,67;San Francisco,59;Seattle,58;" 
      Dim pattern As String = "((\w+(\s\w+)*),(\d+);)+"
      Dim match As Match = Regex.Match(input, pattern)
      If match.Success Then
         Console.WriteLine("Current temperatures:")
         For ctr As Integer = 0 To match.Groups(2).Captures.Count - 1
            Console.WriteLine("{0,-20} {1,3}", match.Groups(2).Captures(ctr).Value, _
                              match.Groups(4).Captures(ctr).Value)
         Next
      End If
   End Sub
End Module
' The example displays the following output:
'       Current temperatures:
'       Miami                 78
'       Chicago               62
'       New York              67
'       San Francisco         59
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string input = "Miami,78;Chicago,62;New York,67;San Francisco,59;Seattle,58;"; 
      string pattern = @"((\w+(\s\w+)*),(\d+);)+";
      Match match = Regex.Match(input, pattern);
      if (match.Success)
      {
         Console.WriteLine("Current temperatures:");
         for (int ctr = 0; ctr < match.Groups[2].Captures.Count; ctr++)
            Console.WriteLine("{0,-20} {1,3}", match.Groups[2].Captures[ctr].Value, 
                              match.Groups[4].Captures[ctr].Value);
      }
   }
}
// The example displays the following output:
//       Current temperatures:
//       Miami                 78
//       Chicago               62
//       New York              67
//       San Francisco         59

Шаблон регулярного выражения определяется, как показано в следующей таблице.

Шаблон

Описание

\w+

Совпадение с одним или несколькими символами слова.

(\s\w+)*

Совпадения с символом пробела в количестве от 0 или выше, за которыми следуют один или несколько символов слова. Этот шаблон ищет совпадения с названиями городов, которые содержат несколько слов. Это третья группа записи.

(\w+(\s\w+)*)

Совпадения с символами слов в количестве от 0 и выше, за которыми следует символ пробела и символы слов в количестве от 0 и выше. Это вторая группа записи.

,

Совпадение с запятой.

(\d+)

Совпадение с одной или несколькими цифрами. Это четвертая группа записи.

;

Совпадение с точкой с запятой (;).

((\w+(\s\w+)*),(\d+);)+

Совпадение с шаблоном из слова, за которым следуют любые дополнительные слова, за которыми следует запятая, одна или несколько цифр, точка с запятой, один или более раз. Это первая группа записи.

К началу

См. также

Ссылки

System.Text.RegularExpressions

Основные понятия

Регулярные выражения в .NET Framework

Элементы языка регулярных выражений