Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
В этой статье описывается объектная модель, используемая при работе с регулярными выражениями .NET.
Механизм регулярных выражений
Механизм регулярных выражений в .NET представлен классом Regex. Механизм отвечает за синтаксический анализ и компиляцию регулярного выражение, а также выполнение операций, которые сопоставляют шаблон регулярного выражения с входной строкой. Этот механизм представляет центральный компонент объектной модели регулярных выражений .NET.
Вы можете использовать механизм регулярных выражений одним из двух способов:
Вызывая статичные методы класса Regex. Параметры метода включают в себя входную строку и шаблон регулярного выражения. Механизм регулярных выражений кэширует регулярные выражения, которые используются в вызовах статичных методов, чтобы повторные вызовы статичных методов регулярных выражений, применяющие одно и то же регулярное выражение, выполнялись относительно быстро.
Создав Regex экземпляр объекта, то есть передав регулярное выражение конструктору класса. В этом случае объект Regex не изменяется (доступен только для чтения) и представляет механизм регулярных выражений, который тесно связана с одним регулярным выражением. Так как регулярные выражения, используемые Regex экземплярами, не кэшируются, не следует создавать экземпляр Regex объекта несколько раз с одинаковым регулярным выражением.
Вы можете вызывать методы класса Regex, чтобы выполнить следующие операции:
- определить, соответствует ли строка шаблону регулярного выражения;
- извлечь одно сопоставление или первое сопоставление;
- извлечь все сопоставления;
- заменить сопоставленную подстроку;
- разделить одну строку на массив строк.
Эти операции описаны в следующих разделах.
Сопоставление шаблона регулярного выражения
Метод Regex.IsMatch возвращает значение true, если строка соответствует шаблону; в противном случае возвращается значение false. Метод IsMatch часто используется для проверки входной строки. Например, следующий код проверяет, содержит ли строка допустимый номер социального страхования для США.
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($"{value} is a valid SSN.");
else
Console.WriteLine($"{value}: Invalid");
}
}
}
// The example displays the following output:
// 111-22-3333 is a valid SSN.
// 111-2-3333: Invalid
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
Возможные интерпретации шаблона регулярного выражения ^\d{3}-\d{2}-\d{4}$ показаны в следующей таблице.
| Расписание | Описание |
|---|---|
^ |
Выделение начала входной строки. |
\d{3} |
Совпадение с тремя десятичными цифрами. |
- |
Выделение дефиса. |
\d{2} |
Совпадение с двумя десятичными цифрами. |
- |
Выделение дефиса. |
\d{4} |
Выделяются 4 десятичные цифры. |
$ |
Соответствует концу входной строки. |
Извлечение одного совпадения или первого совпадения
Метод Regex.Match возвращает объект Match, который содержит сведения о первой подстроке, соответствующей шаблону регулярного выражения. Если свойство Match.Success возвращает значение true (найдено соответствие), вы можете получить информацию о последующих соответствиях, вызвав метод Match.NextMatch. Этот метод можно вызывать, пока свойство Match.Success не вернет значение false. Например, следующий код использует метод Regex.Match(String, String) для поиска первого экземпляра повторяющегося слова в строке. Затем вызывается метод Match.NextMatch для поиска других экземпляров. Пример просматривает свойство Match.Success после каждого вызова метода, чтобы определить, было ли текущее сопоставление успешным и следует ли вызывать метод Match.NextMatch.
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 '{match.Groups[1].Value}' found at position {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.
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.
Возможные интерпретации шаблона регулярного выражения \b(\w+)\W+(\1)\b показаны в следующей таблице.
| Расписание | Описание |
|---|---|
\b |
Сопоставление начинается на границе слова. |
(\w+) |
Совпадение с одним или несколькими символами слова. Это первая группа записи. |
\W+ |
Совпадение с одним или большим числом несловообразующих символов. |
(\1) |
Выделение первой захватываемой строки. Это вторая группа записи. |
\b |
Сопоставление заканчивается на границе слова. |
Извлечение всех совпадений
Метод Regex.Matches возвращает объект MatchCollection, содержащий сведения о всех сопоставлениях, найденных механизмом регулярных выражений во входной строке. Например, предыдущий пример можно изменить, чтобы вызывать метод Matches вместо методов Match и NextMatch.
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 '{match.Groups[1].Value}' found at position {match.Groups[2].Index}.");
}
}
// The example displays the following output:
// Duplicate 'a' found at position 10.
// Duplicate 'that' found at position 22.
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.
Замена сопоставленной подстроки
Метод Regex.Replace заменяет каждую подстроку, соответствующую шаблону регулярного выражения, на указанную строку или шаблон регулярного выражения и возвращает всю замененную входную строку. Например, следующий код добавляет обозначение денежной единицы США перед десятичным числом в строке.
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
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
Возможные интерпретации шаблона регулярного выражения \b\d+\.\d{2}\b показаны в следующей таблице.
| Расписание | Описание |
|---|---|
\b |
Совпадение должно начинаться на границе слова. |
\d+ |
Совпадение с одной или несколькими десятичными цифрами. |
\. |
Сопоставляется точка. |
\d{2} |
Совпадение с двумя десятичными цифрами. |
\b |
Совпадение должно заканчиваться на границе слова. |
Шаблон замены $$$& интерпретируется, как показано в следующей таблице.
| Расписание | Строка замены |
|---|---|
$$ |
Символ доллара ($). |
$& |
Вся сопоставленная подстрока. |
Разделение одной строки на массив строк
Метод Regex.Split разделяет входную строку в позициях, заданных соответствием регулярного выражения. Например, следующий код помещает элементы нумерованного списка в массив строк.
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
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
Возможные интерпретации шаблона регулярного выражения \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 минус 1). 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 всеми соответствиями, найденными во входной строке. Пример перечисляет коллекцию, копирует соответствия в массив строк и записывает позиции символов в целочисленный массив.
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($"'{results[ctr]}' found at position {matchposition[ctr]}.");
}
}
// The example displays the following output:
// 'abc' found at position 3.
// 'abc' found at position 7.
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.
Класс Match
Класс Match представляет результат одного сопоставления регулярного выражения. Доступ к объектам Match можно получить двумя способами:
Извлекая их из объекта MatchCollection, который возвращается методом Regex.Matches. Для извлечения отдельных объектов Match выполните итерацию коллекции, воспользовавшись конструкцией
foreach(в C#) илиFor Each...Next(в Visual Basic), либо используйте свойство MatchCollection.Item[] для извлечения конкретного объекта Match по индексу или по имени. Вы также можете получить отдельные объекты Match из коллекции, циклически проходя по коллекции по индексу (от нуля до числа объектов в коллекции минус 1). Однако этот метод не использует отложенные вычисления, так как он обращается к свойству MatchCollection.Count.Следующий пример извлекает отдельные объекты Match из объекта MatchCollection, циклически перебирая коллекцию с помощью конструкции
foreachилиFor Each...Next. Регулярное выражение просто сопоставляет строку "abc" во входной строке.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($"{match.Value} found at position {match.Index}."); } } // The example displays the following output: // abc found at position 0. // abc found at position 6. // abc found at position 12.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.Вызывая метод Regex.Match, который возвращает объект Match, представляющий первое соответствие в строке или ее части. Вы можете определить, найдено ли соответствие, получив значение свойства
Match.Success. Чтобы извлечь объекты Match, представляющие последующие соответствия, вызывайте метод Match.NextMatch, пока свойствоSuccessполученного объекта Match не будет иметь значениеfalse.Следующий пример использует методы Regex.Match(String, String) и Match.NextMatch для сопоставления строки "abc" во входной строке.
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($"{match.Value} found at position {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.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.
Два свойства класса Match возвращают объекты коллекции:
Свойство Match.Groups возвращает объект GroupCollection, который содержит сведения о подстроках, соответствующих захватываемым группам в шаблоне регулярного выражения.
Свойство
Match.Capturesвозвращает объект CaptureCollection с ограниченным применением. Коллекция не заполняется для объекта Match, свойствоSuccessкоторого имеет значениеfalse. В противном случае она содержит один объект Capture, содержащий такие же данные, что и объект Match.
Дополнительные сведения об этих объектах см. в разделах GroupCollection "Класс" и "Разделы CaptureCollection классов" далее в этой статье.
Два дополнительных свойства класса Match предоставляют сведения о соответствии. Свойство Match.Value возвращает подстроку из входной строки, соответствующую шаблону регулярного выражения. Свойства Match.Index возвращает начальную позицию сопоставленной подстроки во входной строке с основанием ноль.
Класс Match также содержит два метода сопоставления шаблона:
Метод Match.NextMatch ищет совпадение после соответствия, представленного текущим объектом Match, и возвращает объект Match, представляющий соответствие.
Метод Match.Result выполняет указанную замену в сопоставленной строке и возвращает результат.
В следующем примере метод Match.Result используется для добавления символа $ и пробела перед каждым числом из двух дробных разрядов.
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
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
Шаблон регулярного выражения \b\d+(,\d{3})*\.\d{2}\b определяется, как показано в следующей таблице.
| Расписание | Описание |
|---|---|
\b |
Совпадение должно начинаться на границе слова. |
\d+ |
Совпадение с одной или несколькими десятичными цифрами. |
(,\d{3})* |
Совпадение с нулем или несколькими вхождениями запятой, за которыми следуют три десятичные цифры. |
\. |
Совпадение с символом десятичной точки. |
\d{2} |
Совпадение с двумя десятичными цифрами. |
\b |
Совпадение должно заканчиваться на границе слова. |
Шаблон замены $$ $& указывает, что сопоставленную подстроку следует заменить на символ доллара ($) (шаблон $$), пробел и значение соответствия (шаблон $&).
Класс GroupCollection
Свойство Match.Groups возвращает объект GroupCollection, содержащий объекты Group, которые представляют захватываемые группы в одном соответствии. Первый объект Group в коллекции (объект с нулевым индексом) представляет все сопоставление. Каждый последующий объект представляет результаты одной захватываемой группы.
Вы можете извлечь отдельные объекты Group из коллекции, используя свойство GroupCollection.Item[]. Неименованные группы можно извлечь по их номеру в коллекции, а именованные группы — по имени или номеру. Неименованные выделения идут в коллекции первыми и индексируются слева направо в том порядке, в котором они указаны в шаблоне регулярного выражения. Именованные выделения индексируются после неименованных слева направо в том порядке, в котором они указаны в шаблоне регулярного выражения. Чтобы определить, какие нумерованные группы доступны в коллекции, возвращаемой для определенного метода сопоставления регулярного выражения, вызовите метод Regex.GetGroupNumbers экземпляра. Чтобы определить, какие именованные группы доступны в коллекции, вызовите метод Regex.GetGroupNames экземпляра. Оба метода полезны в процедурах общего назначения, которые анализируют соответствия, найденные любым регулярным выражением.
Свойство GroupCollection.Item[] — это индексатор коллекции для C# и свойство объекта по умолчанию для Visual Basic. Это значит, что доступ к отдельным объектам Group можно получить по индексу (или, для именованных групп, по имени) следующим образом:
Group group = match.Groups[ctr];
Dim group As Group = match.Groups(ctr)
В следующем примере определяется регулярное выражение, которое использует конструкции группировки для выделения месяца, дня и года из даты.
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 {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
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
Шаблон регулярного выражения \b(\w+)\s(\d{1,2}),\s(\d{4})\b определяется, как показано в следующей таблице.
| Расписание | Описание |
|---|---|
\b |
Совпадение должно начинаться на границе слова. |
(\w+) |
Совпадение с одним или несколькими символами слова. Это первая группа записи. |
\s |
Соответствует пробелу. |
(\d{1,2}) |
Совпадение с одной или двумя десятичными цифрами. Это вторая группа записи. |
, |
Сопоставление запятой. |
\s |
Соответствует пробелу. |
(\d{4}) |
Выделяются 4 десятичные цифры. Это третья группа записи. |
\b |
Сопоставление заканчивается на границе слова. |
Захватываемая группа
Класс Group представляет результат одной захватываемой группы. Объекты Group, представляющие захватываемые группы, заданные в регулярном выражении, возвращаются свойством Item[] объекта GroupCollection, который возвращается свойством Match.Groups. Свойство Item[] — это индексатор (для C#) и свойство по умолчанию (для Visual Basic) класса Group. Вы также можете извлечь отдельные члены, циклически перебирая коллекцию с помощью конструкции foreach или For Each. Пример см. в предыдущем разделе.
В следующем примере вложенные конструкции группировки используются для записи подстрок в группы. Шаблон регулярного выражения (a(b))c сопоставляет строку "abc". Он назначает подстроку "ab" первой захватываемой группе, а подстроку "b" — второй захватываемой группе.
var matchposition = new List<int>();
var results = new List<string>();
// Define substrings abc, ab, b.
var 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($"{results[ctr]} at position {matchposition[ctr]}");
// The example displays the following output:
// abc at position 3
// ab at position 3
// b at position 4
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
В следующем примере именованные конструкции группировки используются для выделения подстрок из строки, содержащей данные в формате "DATANAME:VALUE", которые регулярное выражение разделяет в позиции двоеточия (:).
var 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
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
Шаблон регулярного выражения ^(?<name>\w+):(?<value>\w+) определяется, как показано в следующей таблице.
| Расписание | Описание |
|---|---|
^ |
Начало совпадения в начале входной строки. |
(?<name>\w+) |
Совпадение с одним или несколькими символами слова. Имя захватываемой группы — name. |
: |
Сопоставление двоеточия. |
(?<value>\w+) |
Совпадение с одним или несколькими символами слова. Имя захватываемой группы — value. |
Свойства класса Group предоставляют сведения о захватываемой группе: свойство Group.Value содержит выделенную подстроку, свойство Group.Index указывает начальную позицию захватываемой группы во входном тексте, свойство Group.Length содержит длину выделенного текста, а свойство Group.Success указывает, соответствует ли подстрока шаблону, заданному захватываемой группой.
Применение квантификаторов к группе (см. раздел Квантификаторы) изменяет связь одного выделения в захватываемой группе двумя способами:
Если квантификатор
*или*?(который указывает ноль или больше соответствий) применен к группе, во входной строке может отсутствовать соответствие захватываемой группе. Если выделенного текста нет, свойства объекта Group задаются, как показано в следующей таблице.Свойство объекта Group Значение SuccessfalseValueString.Empty Length0 Это показывается в следующем примере. В шаблоне регулярного выражения
aaa(bbb)*cccпервая захватываемая группа (подстрока "bbb") может быть сопоставлена ноль или больше раз. Так как входная строка "aaaccc" соответствует шаблону, захватываемая группа не имеет соответствия.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: {match.Value}"); if (match.Groups[1].Success) Console.WriteLine($"Group 1 value: {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.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.Квантификаторы могут сопоставлять множество вхождений шаблона, заданного захватываемой группой. В этом случае свойства
ValueиLengthобъекта Group содержат сведения только о последней выделенной подстроке. Например, следующее регулярное выражение сопоставляет предложение, заканчивающееся на точку. Оно использует две конструкции группировки: первая выделяет отдельные слова вместе с пробелом, вторая выделяет отдельные слова. Как видно из результата выполнения примера, хотя регулярное выражение успешно выделяет все предложение, вторая захватываемая группа выделяет только последнее слово.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: sentenceImports 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
Класс CaptureCollection
Объект Group содержит сведения только о последнем выделении. Однако весь набор выделений, созданный захватываемой группой, по-прежнему доступен из объекта CaptureCollection, возвращаемого свойством Group.Captures. Каждый член коллекции — это объект Capture, представляющий выделение этой захватываемой группы в порядке захвата (и, следовательно, в порядке сопоставления выделенных строк слева направо во входной строке). Вы можете извлечь отдельные объекты Capture из коллекции одним из двух способов:
циклически перебирая коллекцию с помощью конструкции
foreach(для C#) илиFor Each(для Visual Basic);используя свойство CaptureCollection.Item[] для извлечения определенного объекта по индексу. Свойство Item[] — это свойство по умолчанию (для Visual Basic) индексатор (для C#) класса CaptureCollection.
Если квантификатор не применен к захватываемой группе, объект CaptureCollection содержит один объект Capture, который не представляет особого интереса, так как он содержит сведения о том же соответствии, что и объект Group. Если к захватываемой группе применен квантификатор, объект CaptureCollection содержит все выделения захватываемой группы, а последний член коллекции представляет то же выделение, что и объект Group.
Например, если использовать шаблон регулярного выражения ((a(b))c)+ (где квантификатор "+" указывает одно или несколько соответствий) для выделения соответствий из строки "abcabcabc", объект CaptureCollection для каждого объекта Group содержит три члена.
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: '{match.Value}' at position {match.Index}");
GroupCollection groups = match.Groups;
for (int ctr = 0; ctr < groups.Count; ctr++) {
Console.WriteLine($" Group {ctr}: '{groups[ctr].Value}' at position {groups[ctr].Index}");
CaptureCollection captures = groups[ctr].Captures;
for (int ctr2 = 0; ctr2 < captures.Count; ctr2++) {
Console.WriteLine($" Capture {ctr2}: '{captures[ctr2].Value}' at position {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
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 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 для получения нескольких групп выделенных подстрок.
int counter;
Match m;
CaptureCollection cc;
GroupCollection gc;
// Look for groupings of "Abc".
var 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
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
Класс Capture
Класс Capture содержит результаты одного выделения части выражения. Свойство Capture.Value содержит сопоставленный текст, а свойство Capture.Index указывает начальную позицию сопоставленной подстроки во входной строке с основанием ноль.
Следующий пример ищет во входной строке температуру выбранных городов. Запятая (",") используется для разделения города и температуры, а точка с запятой (";") — для разделения данных каждого города. Вся входная строка представляет одно соответствие. В шаблоне регулярного выражения ((\w+(\s\w+)*),(\d+);)+, который используется для анализа строки, название города назначается второй захватываемой группе, а температура — четвертой захватываемой группе.
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
// Seattle 58
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
' Seattle 58
Определение регулярного выражения показано в следующей таблице.
| Расписание | Описание |
|---|---|
\w+ |
Совпадение с одним или несколькими символами слова. |
(\s\w+)* |
Сопоставляется ноль или несколько экземпляров пробела, за которыми следует один или несколько словообразующих символов. Этот шаблон выделяет названия городов из нескольких слов. Это третья группа записи. |
(\w+(\s\w+)*) |
Сопоставляется один или несколько словообразующих символов, за которыми следует ноль или несколько пробелов и один или несколько словообразующих символов. Это вторая группа записи. |
, |
Сопоставление запятой. |
(\d+) |
Сопоставление с одной или несколькими цифрами. Это четвертая группа записи. |
; |
Сопоставление точки с запятой. |
((\w+(\s\w+)*),(\d+);)+ |
Шаблона из слова, за которым следуют другие слова, запятая, одна или несколько цифр и точка запятая сопоставляется один или более раз. Это первая группа записи. |