Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Konstrukcje grupowania delineują podwyrażenia wyrażenia regularnego i przechwytują podciągy ciągu wejściowego. Możesz użyć konstrukcji grupowania, aby wykonać następujące czynności:
- Dopasuj podwyrażenie, które powtarza się w ciągu wejściowym.
- Zastosuj kwantyfikator do podwyrażenia, które ma wiele elementów języka wyrażeń regularnych. Aby uzyskać więcej informacji na temat kwantyfikatorów, zobacz Quantifiers.
- Uwzględnij podwyrażenie w ciągu zwracanym przez metody Regex.Replace i Match.Result.
- Pobierz poszczególne podwyrażenia z Match.Groups właściwości i przetwarzaj je oddzielnie od dopasowanego tekstu jako całości.
W poniższej tabeli wymieniono konstrukcje grupowania obsługiwane przez aparat wyrażeń regularnych platformy .NET i wskazano, czy przechwytują, czy są nieprzechwytujące.
| Konstrukcja grupująca | Przechwytywanie lub brak przechwytywania |
|---|---|
| Dopasowane podwyrażenia | Przechwytywanie |
| Nazwane dopasowane podwyrażenia | Przechwytywanie |
| Równoważenie definicji grup | Przechwytywanie |
| Grupy niezwiązane z hermetyzowaniem | Brak hermetyzacji |
| Opcje grupy | Nieprzechwytujący |
| Asercja dodatnia o zerowej szerokości | Brak hermetyzacji |
| Asercja ujemna o zerowej szerokości | Nieprzechwytujący |
| Asercja dodatnia o zerowej szerokości | Bez przechwytywania |
| Asercja typu lookbehind z ujemną zerową szerokością | Nieprzechwytujący |
| Grupy atomowe | Nieprzechwytujący |
Aby uzyskać informacje na temat grup i modelu obiektów wyrażeń regularnych, zobacz Grupowanie konstrukcji i obiektów wyrażeń regularnych.
Dopasowane podwyrażenia
Następująca konstrukcja grupowania zapisuje dopasowane podwyrażenie:
(
Subexpression)
W tym miejscu wyrażenie podrzędne jest dowolnym prawidłowym wzorcem wyrażenia regularnego. Przechwycenia używające nawiasów są numerowane automatycznie od lewej do prawej na podstawie kolejności nawiasów otwierających użytych w wyrażeniu regularnym, zaczynając od 1. Jednak nazwane grupy przechwytywania są zawsze uporządkowane jako ostatnie po nienazwanych grupach przechwytywania. Przechwycenie o numerze 0 jest tekstem dopasowanym do całego wzorca wyrażenia regularnego.
Uwaga
Domyślnie (element języka podwyrażenia przechwytuje dopasowane podwyrażenie) . Jeśli jednak parametr wzorca wyrażenia regularnego zawiera flagę RegexOptions.ExplicitCapture, lub jeśli opcja n jest stosowana do tego podwyrażenia (zobacz Opcje grupy w dalszej części tego artykułu), dopasowane wyrażenie podrzędne nie jest przechwytywane.
Dostęp do przechwyconych grup można uzyskać na cztery sposoby:
Używając konstrukcji odwołania wstecznego w wyrażeniu regularnym. Dopasowane podwyrażenie jest przywoływane w tym samym wyrażeniu regularnym przy użyciu składni
\numer, gdzie numer jest liczbą porządkową przechwyconego podwyrażenia.Używając konstrukcji nazwanej referencji w wyrażeniu regularnym. Dopasowane podwyrażenie jest przywoływane w tym samym wyrażeniu regularnym przy użyciu składni
\k<nazwa>, gdzie nazwa to nazwa grupy przechwytywania, lub\k<liczba>, gdzie liczba jest liczbą porządkową grupy przechwytywania. Grupa przechwytywania ma domyślną nazwę, która jest identyczna z numerem porządkowym. Aby uzyskać więcej informacji, zajrzyj do Nazwane dopasowane podwyrażenia w dalszej części tego tematu.Używając sekwencji zastępczej
$numeru w Regex.Replace wywołaniu metody lub Match.Result wywołaniu metody, gdzie numer jest numerem porządkowym przechwyconego podwyrażenia.Programowo poprzez użycie obiektu GroupCollection zwróconego przez właściwość Match.Groups. Element na pozycji zero w kolekcji reprezentuje całe dopasowanie wyrażenia regularnego. Każdy kolejny członek reprezentuje dopasowane wyrażenie podrzędne. Aby uzyskać więcej informacji, zobacz sekcję Grupowanie konstrukcji i obiektów wyrażeń regularnych .
Poniższy przykład ilustruje wyrażenie regularne, które identyfikuje zduplikowane wyrazy w tekście. Dwie grupy przechwytujące we wzorcu wyrażeń regularnych reprezentują dwa wystąpienia zduplikowanego słowa. Drugie wystąpienie jest przechwytywane, aby zgłosić jego pozycję początkową w ciągu wejściowym.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"(\w+)\s(\1)\W";
string input = "He said that that was the the correct answer.";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
Console.WriteLine($"Duplicate '{match.Groups[1].Value}' found at positions {match.Groups[1].Index} and {match.Groups[2].Index}.");
}
}
// The example displays the following output:
// Duplicate 'that' found at positions 8 and 13.
// Duplicate 'the' found at positions 22 and 26.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "(\w+)\s(\1)\W"
Dim input As String = "He said that that was the the correct answer."
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
Console.WriteLine("Duplicate '{0}' found at positions {1} and {2}.", _
match.Groups(1).Value, match.Groups(1).Index, match.Groups(2).Index)
Next
End Sub
End Module
' The example displays the following output:
' Duplicate 'that' found at positions 8 and 13.
' Duplicate 'the' found at positions 22 and 26.
Wzorzec wyrażenia regularnego jest następujący:
(\w+)\s(\1)\W
W poniższej tabeli przedstawiono sposób interpretowania wzorca wyrażenia regularnego.
| Wzorzec | opis |
|---|---|
(\w+) |
Dopasowuje jeden lub więcej znaków słów. Jest to pierwsza grupa przechwytywania. |
\s |
Dopasowuje znak odstępu. |
(\1) |
Dopasuj łańcuch znaków w pierwszej przechwyconej grupie. Jest to druga grupa przechwytywania. Przykład przypisuje go do przechwyconej grupy, aby można było pobrać pozycję początkową zduplikowanego wyrazu Match.Index z właściwości . |
\W |
Dopasuj znak inny niż wyraz, w tym biały znak i znak interpunkcyjny. Zapobiega to dopasowywaniu wzorca wyrażenia regularnego do słowa rozpoczynającego się od wyrazu z pierwszej przechwyconej grupy. |
Nazwane dopasowane podwyrażenia
Następująca konstrukcja grupowania przechwytuje dopasowane podwyrażenie i umożliwia dostęp do niej według nazwy lub liczby:
(?<name>subexpression)
lub
(?'name'subexpression)
Tutaj nazwa jest prawidłową nazwą grupy, a wyrażenie podrzędne jest dowolnym prawidłowym wzorcem wyrażenia regularnego. nazwa nie może zawierać żadnych znaków interpunkcyjnych i nie może zaczynać się od liczby.
Uwaga
RegexOptions Jeśli parametr metody dopasowywania wzorca wyrażenia regularnego zawiera flagę RegexOptions.ExplicitCapture lub jeśli n opcja jest stosowana do tego podwyrażenia (zobacz Opcje grupy w dalszej części tego tematu), jedynym sposobem przechwytywania podwyrażenia jest jawne nazwanie grup przechwytujących.
Dostęp do nazwanych grup przechwyconych można uzyskać w następujący sposób:
Używając konstrukcji nazwanego odwołania wstecznego w wyrażeniu regularnym. Dopasowane podwyrażenie jest przywoływane w tym samym wyrażeniu regularnym przez użycie składni
\k<nazwa>, gdzie nazwa jest nazwą przechwyconego podwyrażenia.Używając konstrukcji odwołania wstecznego w wyrażeniu regularnym. Dopasowane podwyrażenie jest odwoływane w tym samym wyrażeniu regularnym przy użyciu składni
\liczba, gdzie liczba jest liczbą porządkową wyłapanego podwyrażenia. Nazwane dopasowane podwyrażenia są numerowane kolejno od lewej do prawej po dopasowaniu.Używając sekwencji zastępczej
${nazwa}w wywołaniu metody Regex.Replace lub Match.Result, gdzie nazwa jest nazwą przechwyconego podwyrażenia.Używając sekwencji zastępczej
$numer w wywołaniu metody Regex.Replace lub Match.Result, gdzie numer jest numerem porządkowym przechwyconego podwyrażenia.Programowo, używając obiektu GroupCollection, zwróconego przez właściwość Match.Groups. Element członkowski na pozycji zero w kolekcji reprezentuje całe dopasowanie wyrażenia regularnego. Każdy kolejny człon reprezentuje dopasowane podwyrażenie. Nazwane przechwycone grupy są przechowywane w kolekcji po ponumerowanych grupach przechwyconych.
Programowo, podając nazwę podwyrażenia indeksatorowi GroupCollection obiektu (w języku C#) lub jej Item[] właściwości (w Visual Basic).
Prosty wzorzec wyrażenia regularnego ilustruje sposób, w jaki numerowane (nienazwane) i nazwane grupy mogą być przywoływane programowo lub przy użyciu składni języka wyrażeń regularnych. Regularne wyrażenie ((?<One>abc)\d+)?(?<Two>xyz)(.*) tworzy następujące grupy przechwytujące według liczby i według nazwy. Pierwsza grupa przechwytywania (liczba 0) zawsze odnosi się do całego wzorca. (Nazwane grupy są zawsze uporządkowane jako ostatnie).
| Liczba | Nazwisko | Wzorzec |
|---|---|---|
| 0 | 0 (nazwa domyślna) | ((?<One>abc)\d+)?(?<Two>xyz)(.*) |
| 1 | 1 (nazwa domyślna) | ((?<One>abc)\d+) |
| 2 | 2 (nazwa domyślna) | (.*) |
| 3 | Jeden | (?<One>abc) |
| 4 | Dwa | (?<Two>xyz) |
Poniższy przykład ilustruje wyrażenie regularne, które identyfikuje zduplikowane wyrazy i słowo, które natychmiast następuje po każdym zduplikowanym słowie. Wzorzec wyrażenia regularnego definiuje dwa nazwane podwyrażenia: duplicateWord, które reprezentuje zduplikowane słowo, i nextWord, które reprezentuje słowo, które następuje po zduplikowanym.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"(?<duplicateWord>\w+)\s\k<duplicateWord>\W(?<nextWord>\w+)";
string input = "He said that that was the the correct answer.";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
Console.WriteLine($"A duplicate '{match.Groups["duplicateWord"].Value}' at position {match.Groups["duplicateWord"].Index} is followed by '{match.Groups["nextWord"].Value}'.");
}
}
// The example displays the following output:
// A duplicate 'that' at position 8 is followed by 'was'.
// A duplicate 'the' at position 22 is followed by 'correct'.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "(?<duplicateWord>\w+)\s\k<duplicateWord>\W(?<nextWord>\w+)"
Dim input As String = "He said that that was the the correct answer."
Console.WriteLine(Regex.Matches(input, pattern, RegexOptions.IgnoreCase).Count)
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
Console.WriteLine("A duplicate '{0}' at position {1} is followed by '{2}'.", _
match.Groups("duplicateWord").Value, match.Groups("duplicateWord").Index, _
match.Groups("nextWord").Value)
Next
End Sub
End Module
' The example displays the following output:
' A duplicate 'that' at position 8 is followed by 'was'.
' A duplicate 'the' at position 22 is followed by 'correct'.
Wzorzec wyrażenia regularnego jest następujący:
(?<duplicateWord>\w+)\s\k<duplicateWord>\W(?<nextWord>\w+)
W poniższej tabeli przedstawiono sposób interpretowania wyrażenia regularnego.
| Wzorzec | opis |
|---|---|
(?<duplicateWord>\w+) |
Dopasowuje jeden lub więcej znaków słów. Nadaj tej grupie przechwytywania nazwę duplicateWord. |
\s |
Dopasowuje znak odstępu. |
\k<duplicateWord> |
Dopasuj ciąg z przechwyconej grupy o nazwie duplicateWord. |
\W |
Dopasuj znak inny niż wyraz, w tym biały znak i znak interpunkcyjny. Zapobiega to dopasowywaniu wzorca wyrażenia regularnego do słowa rozpoczynającego się od wyrazu z pierwszej przechwyconej grupy. |
(?<nextWord>\w+) |
Dopasowuje jeden lub więcej znaków słów. Nadaj tej grupie przechwytywania nazwę nextWord. |
Nazwę grupy można powtórzyć w wyrażeniu regularnym. Można na przykład nazwać digitwięcej niż jedną grupę, jak pokazano w poniższym przykładzie. W przypadku zduplikowanych nazw wartość obiektu Group jest określana przez ostatnie pomyślne przechwycenie w ciągu wejściowym. Ponadto element CaptureCollection jest wypełniany informacjami o każdym przechwyceniu, tak jak gdyby nazwa grupy nie została zduplikowana.
W poniższym przykładzie wyrażenie \D+(?<digit>\d+)\D+(?<digit>\d+)? regularne zawiera dwa wystąpienia grupy o nazwie digit. Pierwsza digit nazwana grupa przechwytuje jedną lub więcej cyfr. Druga digit nazwana grupa przechwytuje zero lub jedno wystąpienie jednego lub więcej znaków cyfry. Jak pokazano w danych wyjściowych z przykładu, jeśli druga grupa wyłapująca pomyślnie dopasuje tekst, to wartość tego tekstu określa wartość obiektu Group. Jeśli druga grupa przechwytywania nie jest zgodna z ciągiem wejściowym, wartość ostatniego pomyślnego dopasowania definiuje wartość Group obiektu.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
String pattern = @"\D+(?<digit>\d+)\D+(?<digit>\d+)?";
String[] inputs = { "abc123def456", "abc123def" };
foreach (var input in inputs) {
Match m = Regex.Match(input, pattern);
if (m.Success) {
Console.WriteLine($"Match: {m.Value}");
for (int grpCtr = 1; grpCtr < m.Groups.Count; grpCtr++) {
Group grp = m.Groups[grpCtr];
Console.WriteLine($"Group {grpCtr}: {grp.Value}");
for (int capCtr = 0; capCtr < grp.Captures.Count; capCtr++)
Console.WriteLine($" Capture {capCtr}: {grp.Captures[capCtr].Value}");
}
}
else {
Console.WriteLine("The match failed.");
}
Console.WriteLine();
}
}
}
// The example displays the following output:
// Match: abc123def456
// Group 1: 456
// Capture 0: 123
// Capture 1: 456
//
// Match: abc123def
// Group 1: 123
// Capture 0: 123
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\D+(?<digit>\d+)\D+(?<digit>\d+)?"
Dim inputs() As String = {"abc123def456", "abc123def"}
For Each input As String In inputs
Dim m As Match = Regex.Match(input, pattern)
If m.Success Then
Console.WriteLine("Match: {0}", m.Value)
For grpCtr As Integer = 1 to m.Groups.Count - 1
Dim grp As Group = m.Groups(grpCtr)
Console.WriteLine("Group {0}: {1}", grpCtr, grp.Value)
For capCtr As Integer = 0 To grp.Captures.Count - 1
Console.WriteLine(" Capture {0}: {1}", capCtr,
grp.Captures(capCtr).Value)
Next
Next
Else
Console.WriteLine("The match failed.")
End If
Console.WriteLine()
Next
End Sub
End Module
' The example displays the following output:
' Match: abc123def456
' Group 1: 456
' Capture 0: 123
' Capture 1: 456
'
' Match: abc123def
' Group 1: 123
' Capture 0: 123
W poniższej tabeli przedstawiono sposób interpretowania wyrażenia regularnego.
| Wzorzec | opis |
|---|---|
\D+ |
Dopasuj co najmniej jeden znak cyfry innej niż dziesiętna. |
(?<digit>\d+) |
Dopasuj co najmniej jeden znak cyfry dziesiętnej. Przypisz dopasowanie do grupy o nazwie digit. |
\D+ |
Dopasuj co najmniej jeden znak cyfry innej niż dziesiętna. |
(?<digit>\d+)? |
Dopasuj zero lub jedno wystąpienie co najmniej jednego znaku cyfry dziesiętnej. Przypisz dopasowanie do grupy nazwanej digit. |
Równoważenie definicji grup
Definicja grupy równoważenia usuwa definicję wcześniej zdefiniowanej grupy i przechowuje w bieżącej grupie interwał między wcześniej zdefiniowaną grupą a bieżącą grupą. Ta konstrukcja grupowania ma następujący format:
(?<name1-name2>subexpression)
lub:
(?'name1-name2' subexpression)
Tutaj nazwa1 to bieżąca grupa (opcjonalnie), nazwa2 jest wcześniej zdefiniowaną grupą, a podwyrażenie jest dowolnym prawidłowym wzorcem wyrażenia regularnego. Definicja grupy bilansowania usuwa definicję name2 i przechowuje interwał między name2 i name1 w name1. Jeśli żadna grupa name2 nie jest zdefiniowana, dopasowanie się wycofuje. Ponieważ usunięcie ostatniej definicji name2 ujawnia poprzednią definicję name2, ta konstrukcja umożliwia użycie stosu przechwytywania dla grupy name2 jako licznika do śledzenia zagnieżdżonych konstrukcji, takich jak nawiasy lub klamry.
Definicja grupy równoważenia używa nazwy 2 jako stosu. Znak początkowy każdej zagnieżdżonej konstrukcji jest umieszczany w grupie i w jej Group.Captures kolekcji. Gdy znak zamykający zostanie dopasowany, jego odpowiedni znak otwierający zostanie usunięty z grupy, a Captures kolekcja zostanie zmniejszona o jeden. Po dopasowaniu znaków otwierających i zamykających wszystkich zagnieżdżonych konstrukcji nazwa2 jest pusta.
Uwaga
Po zmodyfikowaniu wyrażenia regularnego w poniższym przykładzie w celu użycia odpowiedniego znaku otwierania i zamykania zagnieżdżonej konstrukcji można użyć go do obsługi większości zagnieżdżonych konstrukcji, takich jak wyrażenia matematyczne lub wiersze kodu programu, które zawierają wiele zagnieżdżonych wywołań metod.
W poniższym przykładzie użyto definicji grupy równoważenia, aby dopasować nawiasy ostrokątne lewy i prawy (<>) w ciągu wejściowym. W przykładzie zdefiniowano dwie nazwane grupy Open i Close, które są używane jak stos do śledzenia pasujących par nawiasów kątowych. Każdy przechwycony lewy nawias kątowy jest umieszczany w kolekcji przechwyceń grupy Open, a każdy przechwycony prawy nawias kątowy jest umieszczany w kolekcji przechwyceń grupy Close. Definicja grupy równoważenia gwarantuje, że dla każdego lewego nawiasu kątowego istnieje pasujący prawy nawias kątowy. Jeśli tak nie jest, końcowy podwzorzec (?(Open)(?!)) jest obliczany tylko wtedy, gdy grupa Open nie jest pusta (a więc, jeśli wszystkie zagnieżdżone konstrukcje nie zostały zamknięte). Jeśli końcowy podwzorzec jest analizowany, dopasowanie kończy się niepowodzeniem, ponieważ (?!) podwzorzec jest ujemną asercją wyprzedzającą o zerowej szerokości, która zawsze kończy się niepowodzeniem.
using System;
using System.Text.RegularExpressions;
class Example
{
public static void Main()
{
string pattern = "^[^<>]*" +
"(" +
"((?'Open'<)[^<>]*)+" +
"((?'Close-Open'>)[^<>]*)+" +
")*" +
"(?(Open)(?!))$";
string input = "<abc><mno<xyz>>";
Match m = Regex.Match(input, pattern);
if (m.Success == true)
{
Console.WriteLine($"Input: \"{input}\" \nMatch: \"{m}\"");
int grpCtr = 0;
foreach (Group grp in m.Groups)
{
Console.WriteLine($" Group {grpCtr}: {grp.Value}");
grpCtr++;
int capCtr = 0;
foreach (Capture cap in grp.Captures)
{
Console.WriteLine($" Capture {capCtr}: {cap.Value}");
capCtr++;
}
}
}
else
{
Console.WriteLine("Match failed.");
}
}
}
// The example displays the following output:
// Input: "<abc><mno<xyz>>"
// Match: "<abc><mno<xyz>>"
// Group 0: <abc><mno<xyz>>
// Capture 0: <abc><mno<xyz>>
// Group 1: <mno<xyz>>
// Capture 0: <abc>
// Capture 1: <mno<xyz>>
// Group 2: <xyz
// Capture 0: <abc
// Capture 1: <mno
// Capture 2: <xyz
// Group 3: >
// Capture 0: >
// Capture 1: >
// Capture 2: >
// Group 4:
// Group 5: mno<xyz>
// Capture 0: abc
// Capture 1: xyz
// Capture 2: mno<xyz>
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "^[^<>]*" & _
"(" + "((?'Open'<)[^<>]*)+" & _
"((?'Close-Open'>)[^<>]*)+" + ")*" & _
"(?(Open)(?!))$"
Dim input As String = "<abc><mno<xyz>>"
Dim rgx AS New Regex(pattern) '
Dim m As Match = Regex.Match(input, pattern)
If m.Success Then
Console.WriteLine("Input: ""{0}"" " & vbCrLf & "Match: ""{1}""", _
input, m)
Dim grpCtr As Integer = 0
For Each grp As Group In m.Groups
Console.WriteLine(" Group {0}: {1}", grpCtr, grp.Value)
grpCtr += 1
Dim capCtr As Integer = 0
For Each cap As Capture In grp.Captures
Console.WriteLine(" Capture {0}: {1}", capCtr, cap.Value)
capCtr += 1
Next
Next
Else
Console.WriteLine("Match failed.")
End If
End Sub
End Module
' The example displays the following output:
' Input: "<abc><mno<xyz>>"
' Match: "<abc><mno<xyz>>"
' Group 0: <abc><mno<xyz>>
' Capture 0: <abc><mno<xyz>>
' Group 1: <mno<xyz>>
' Capture 0: <abc>
' Capture 1: <mno<xyz>>
' Group 2: <xyz
' Capture 0: <abc
' Capture 1: <mno
' Capture 2: <xyz
' Group 3: >
' Capture 0: >
' Capture 1: >
' Capture 2: >
' Group 4:
' Group 5: mno<xyz>
' Capture 0: abc
' Capture 1: xyz
' Capture 2: mno<xyz>
Wzorzec wyrażenia regularnego to:
^[^<>]*(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)*(?(Open)(?!))$
Wyrażenie regularne jest interpretowane w następujący sposób:
| Wzorzec | opis |
|---|---|
^ |
Rozpocznij na początku ciągu. |
[^<>]* |
Dopasuj zero lub więcej znaków, które nie są nawiasami ostrokątnymi lewego lub prawego kąta. |
(?'Open'<) |
Dopasuj lewy nawias kątowy i przypisz go do grupy o nazwie Open. |
[^<>]* |
Dopasuj zero lub więcej znaków, które nie są nawiasami kątowymi lewymi lub prawymi. |
((?'Open'<)[^<>]*)+ |
Dopasuj co najmniej jedno wystąpienie lewego nawiasu kątowego, po którym następuje zero lub więcej znaków, które nie są lewymi ani prawymi nawiasami kątowymi. Jest to druga grupa przechwytywania. |
(?'Close-Open'>) |
Dopasuj prawy nawias kątowy, przypisz podciąg między grupą Open a bieżącą grupą do grupy Close, i usuń definicję grupy Open. |
[^<>]* |
Dopasuj zero lub więcej wystąpień dowolnego znaku, który nie jest ani lewym, ani prawym nawiasem kątowym. |
((?'Close-Open'>)[^<>]*)+ |
Dopasuj jedno lub więcej wystąpień prawego nawiasu kątowego, po którym następuje zero lub więcej wystąpień dowolnego znaku, który nie jest ani lewym, ani prawym nawiasem kątowym. Podczas dopasowywania prawego nawiasu kątowego przypisz podciąg między grupą Open a bieżącą grupą do grupy Close i usuń definicję grupy Open. Jest to trzecia grupa przechwytywania. |
(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)* |
Dopasuj zero lub więcej wystąpień następującego wzorca: co najmniej jedno wystąpienie nawiasu kątowego po lewej stronie, po którym następuje zero lub więcej znaków nawiasu niekątnego, po którym następuje jedno lub więcej wystąpień nawiasu kątowego prawego, po którym następuje zero lub więcej wystąpień nawiasów niekątnych. Podczas dopasowywania prawego nawiasu kątowego, usuń definicję grupy Open i przypisz podciąg pomiędzy grupą Open a bieżącą grupą do grupy Close. Jest to pierwsza grupa przechwytywania. |
(?(Open)(?!)) |
Jeśli grupa Open istnieje, porzuć dopasowanie, jeśli można dopasować pusty ciąg, ale nie zmieniaj pozycji mechanizmu wyrażeń regularnych w ciągu. Jest to asercja ujemna o zerowej szerokości. Ponieważ pusty ciąg jest zawsze niejawnie obecny w ciągu wejściowym, to dopasowanie zawsze kończy się niepowodzeniem. Niepowodzenie tego dopasowania wskazuje, że nawiasy kątowe nie są zrównoważone. |
$ |
Dopasuj koniec ciągu wejściowego. |
Końcowe podwyrażenie, (?(Open)(?!)), wskazuje, czy konstrukcje zagnieżdżenia w ciągu wejściowym są prawidłowo zrównoważone (na przykład, czy każdy lewy znak mniejszości jest dopasowany prawym nawiasem kątowym). Używa dopasowywania warunkowego w oparciu o prawidłową przechwyconą grupę; aby uzyskać więcej informacji, zobacz Konstrukcje alternatywne. Jeśli grupa Open jest zdefiniowana, aparat wyrażeń regularnych próbuje dopasować podwyrażenie (?!) w ciągu wejściowym. Grupa Open powinna być zdefiniowana tylko wtedy, gdy konstrukcje zagnieżdżenia są niezbalansowane. W związku z tym wzorzec, który ma być dopasowany w ciągu wejściowym, powinien być taki, który zawsze powoduje niepowodzenie dopasowania. W takim przypadku (?!) jest ujemną asercją wyprzedzającą o zerowej szerokości, która zawsze kończy się niepowodzeniem, ponieważ pusty ciąg jest zawsze niejawnie obecny na następnym miejscu w ciągu wejściowym.
W tym przykładzie aparat wyrażeń regularnych oblicza ciąg wejściowy "<abc><mno<xyz>>", jak pokazano w poniższej tabeli.
| Krok | Wzorzec | Wynik |
|---|---|---|
| 1 | ^ |
Rozpoczyna dopasowanie na początku ciągu wejściowego |
| 2 | [^<>]* |
Wyszukuje znaki inne niż nawias kątowy przed lewym nawiasem kątowym; nie znajduje dopasowań. |
| 3 | (((?'Open'<) |
Pasuje do lewego nawiasu kątowego w ciągu "<abc>" i przypisuje go do Open grupy. |
| 4 | [^<>]* |
Pasuje do "abc". |
| 5 | )+ |
"<abc" to wartość drugiej przechwyconej grupy. Następny znak w ciągu wejściowym nie jest lewym nawiasem kątowym, więc silnik wyrażeń regularnych nie zapętla się z powrotem do (?'Open'<)[^<>]*) podwzorca. |
| 6 | ((?'Close-Open'>) |
Dopasowuje prawy nawias kątowy w ciągu "<abc>", przypisuje "abc", czyli podciąg między grupą Open a prawym nawiasem kątowym, do grupy Close, oraz usuwa bieżącą wartość ("<") grupy Open, pozostawiając ją pustą. |
| 7 | [^<>]* |
Wyszukuje znaki nawiasu niekątnego po prawym nawiasie kwadratowym; wyszukuje brak dopasowań. |
| 8 | )+ |
Wartość trzeciej przechwyconej grupy to ">". Następny znak w ciągu wejściowym nie jest nawiasem prostym, więc aparat wyrażeń regularnych nie zapętla się z powrotem do ((?'Close-Open'>)[^<>]*) podwzorca. |
| 9 | )* |
Wartość pierwszej przechwyconej grupy to "<abc>". Następny znak w ciągu wejściowym to lewy nawias kątowy, więc aparat wyrażeń regularnych cofa się do podwzorca (((?'Open'<). |
| 10 | (((?'Open'<) |
Pasuje do lewego nawiasu kątowego w ciągu "<mno" i przypisuje go do grupy Open. Jego Group.Captures kolekcja ma teraz pojedynczą wartość "<". |
| 11 | [^<>]* |
Pasuje do "mno". |
| 12 | )+ |
"<mno" to wartość drugiej przechwyconej grupy. Kolejny znak w ciągu wejściowym to lewy nawias kątowy, więc aparat wyrażeń regularnych wraca ponownie do (?'Open'<)[^<>]*) podwzorca. |
| 13 | (((?'Open'<) |
Dopasowuje lewy nawias kątowy w ciągu "<xyz>" i przypisuje go do grupy Open. Kolekcja Group.Captures grupy Open zawiera teraz dwa przechwycone elementy: lewy znak kątowy z "<mno" oraz lewy znak kątowy z "<xyz>". |
| 14 | [^<>]* |
Dopasowanie do "xyz". |
| 15 | )+ |
"<xyz" to wartość drugiej przechwyconej grupy. Następny znak w ciągu wejściowym nie jest nawiasem ostrym, więc silnik wyrażeń regularnych nie zapętla się z powrotem do (?'Open'<)[^<>]*) podwzorca. |
| 16 | ((?'Close-Open'>) |
Pasuje do prawego nawiasu kątowego w ciągu "<xyz>". "xyz", przypisuje podciąg znajdujący się między grupą Open a prawym nawiasem kątowym do grupy Close i usuwa aktualną wartość grupy Open. Wartość poprzedniego przechwytywania (lewy nawias kątowy w "<mno") staje się bieżącą wartością grupy Open. Kolekcja grupy CapturesOpen zawiera obecnie pojedynczy element, nawias z "<xyz>". |
| 17 | [^<>]* |
Wyszukuje znaki inne niż nawiasy kątowe; nie znajduje dopasowań. |
| 18 | )+ |
Wartość trzeciej przechwyconej grupy to ">". Następny znak w ciągu wejściowym jest prawym nawiasem kątowym, więc silnik wyrażeń regularnych wraca do ((?'Close-Open'>)[^<>]*) podwzorca. |
| 19 | ((?'Close-Open'>) |
Pasuje do końcowego prawego nawiasu kątowego w "xyz>>", przypisuje "mno<xyz>" (podciąg między grupą Open a prawym nawiasem kątowym) do grupy Close, i usuwa bieżącą wartość grupy Open. Grupa Open jest teraz pusta. |
| 20 | [^<>]* |
Wyszukuje znaki nawiasu niekątnego; wyszukuje brak dopasowań. |
| 21 | )+ |
Wartość trzeciej przechwyconej grupy to ">". Następny znak w ciągu wejściowym nie jest nawiasem ostrym, więc silnik wyrażeń regularnych nie zapętla się z powrotem do ((?'Close-Open'>)[^<>]*) podwzorca. |
| 22 | )* |
Wartość pierwszej przechwyconej grupy to "<mno<xyz>>". Następny znak w ciągu wejściowym nie jest lewym nawiasem kątowym, więc mechanizm wyrażeń regularnych nie zapętla się z powrotem do podwzorca. |
| 23 | (?(Open)(?!)) |
Open grupa nie jest zdefiniowana, więc nie podjęto próby dopasowania. |
| 24 | $ |
Pasuje do końca ciągu wejściowego. |
Grupy niezwiązane z hermetyzowaniem
Poniższa konstrukcja grupowania nie przechwytuje podłańcucha pasującego do podwyrażenia.
(?:subexpression)
W tym miejscu wyrażenie podrzędne jest dowolnym prawidłowym wzorcem wyrażenia regularnego. Niekaptywizująca konstrukcja grupy jest zwykle używana, gdy kwantyfikator jest stosowany do grupy, ale podciągi przechwytywane przez grupę nie są interesujące.
Uwaga
Jeśli wyrażenie regularne zawiera zagnieżdżone konstrukcje grupowania, zewnętrzna niewyłapująca konstrukcja grupy nie ma zastosowania do wewnętrznych zagnieżdżonych konstruktów grupowania.
W poniższym przykładzie pokazano wyrażenie regularne, które zawiera grupy nieprzechwytujące. Należy pamiętać, że dane wyjściowe nie zawierają żadnych przechwyconych grup.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"(?:\b(?:\w+)\W*)+\.";
string input = "This is a short sentence.";
Match match = Regex.Match(input, pattern);
Console.WriteLine($"Match: {match.Value}");
for (int ctr = 1; ctr < match.Groups.Count; ctr++)
Console.WriteLine($" Group {ctr}: {match.Groups[ctr].Value}");
}
}
// The example displays the following output:
// Match: This is a short sentence.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "(?:\b(?:\w+)\W*)+\."
Dim input As String = "This is a short sentence."
Dim match As Match = Regex.Match(input, pattern)
Console.WriteLine("Match: {0}", match.Value)
For ctr As Integer = 1 To match.Groups.Count - 1
Console.WriteLine(" Group {0}: {1}", ctr, match.Groups(ctr).Value)
Next
End Sub
End Module
' The example displays the following output:
' Match: This is a short sentence.
Wyrażenie regularne (?:\b(?:\w+)\W*)+\. pasuje do zdania, które jest zakończone kropką. Ponieważ wyrażenie regularne koncentruje się na zdaniach, a nie na pojedynczych słowach, konstrukcje grupowania są używane wyłącznie jako kwantyfikatory. Wzorzec wyrażenia regularnego jest interpretowany, jak pokazano w poniższej tabeli.
| Wzorzec | opis |
|---|---|
\b |
Rozpocznij dopasowywanie na granicy wyrazu. |
(?:\w+) |
Dopasowuje jeden lub więcej znaków słów. Nie przypisuj dopasowanego tekstu do przechwyconej grupy. |
\W* |
Dopasuj zero lub więcej znaków nie będących częścią wyrazów. |
(?:\b(?:\w+)\W*)+ |
Dopasuj wzorzec co najmniej jednego znaku alfanumerycznego, który zaczyna się na granicy wyrazu, a po nim następuje zero lub więcej znaków nienależących do słowa, powtarzające się co najmniej raz. Nie przypisuj dopasowanego tekstu do przechwyconej grupy. |
\. |
Dopasuj okres. |
Opcje grupy
Następująca konstrukcja grupowania ma zastosowanie lub wyłącza określone opcje w ramach podwyrażenia:
(?imnsx-imnsx:
Subexpression)
W tym miejscu wyrażenie podrzędne jest dowolnym prawidłowym wzorcem wyrażenia regularnego. Na przykład (?i-s:) włącza ignorowanie wielkości liter i wyłącza tryb jednoliniowy. Aby uzyskać więcej informacji na temat opcji wbudowanych, które można określić, zobacz Opcje wyrażeń regularnych.
Uwaga
Można określić opcje, które mają zastosowanie do całego wyrażenia regularnego, a nie do podexpressionu przy użyciu konstruktora System.Text.RegularExpressions.Regex klasy lub metody statycznej. Można również określić opcje wbudowane, które mają zastosowanie po określonym punkcie w wyrażeniu regularnym, przy użyciu konstrukcji języka (?imnsx-imnsx).
Konstrukcja opcji grupowych nie jest grupą przechwytywającą. Oznacza to, że chociaż każda część ciągu przechwycona przez podwyrażenie jest uwzględniona w dopasowaniu, nie jest włączana do przechwyconej grupy ani nie jest wykorzystywana do wypełniania obiektu GroupCollection.
Na przykład regularne wyrażenie \b(?ix: d \w+)\s w poniższym przykładzie wykorzystuje wbudowane opcje w konstrukcję grupującą, aby umożliwić dopasowywanie bez rozróżniania wielkości liter oraz ignorowanie białych znaków wzorca w identyfikacji wszystkich wyrazów zaczynających się na literę "d". Wyrażenie regularne jest definiowane, jak pokazano w poniższej tabeli.
| Wzorzec | opis |
|---|---|
\b |
Rozpocznij dopasowywanie na granicy wyrazu. |
(?ix: d \w+) |
Stosując dopasowanie bez rozróżniania wielkości liter i pomijając białe znaki w tym wzorcu, dopasuj "d" po którym następuje co najmniej jeden znak alfanumeryczny. |
\s |
Dopasowuje znak odstępu. |
string pattern = @"\b(?ix: d \w+)\s";
string input = "Dogs are decidedly good pets.";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine($"'{match.Value}// found at index {match.Index}.");
// The example displays the following output:
// 'Dogs // found at index 0.
// 'decidedly // found at index 9.
Dim pattern As String = "\b(?ix: d \w+)\s"
Dim input As String = "Dogs are decidedly good pets."
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("'{0}' found at index {1}.", match.Value, match.Index)
Next
' The example displays the following output:
' 'Dogs ' found at index 0.
' 'decidedly ' found at index 9.
Asercje dodatnie o zerowej szerokości spojrzenia w przód
Następująca konstrukcja grupowania definiuje asercja dodatnią o zerowej szerokości:
(?=
Subexpression)
W tym miejscu wyrażenie podrzędne jest dowolnym wzorcem wyrażenia regularnego. Aby dopasowanie zakończyło się pomyślnie, ciąg wejściowy musi być zgodny ze wzorcem wyrażenia regularnego w podwyrażeniu, chociaż dopasowany podciąg nie jest uwzględniany w wyniku tego dopasowania. Dodatnia asercja patrząca w przyszłość o zerowej szerokości nie powoduje cofania.
Zazwyczaj na końcu wzorca wyrażenia regularnego znajduje się asercja wyprzedzająca dodatnia o zerowej szerokości. Definiuje podciąg, który musi zostać znaleziony na końcu ciągu, aby dopasowanie mogło wystąpić, ale ten podciąg nie powinien być uwzględniony w dopasowaniu. Jest to również przydatne do zapobiegania nadmiernemu cofaniu się. Aby upewnić się, że określona przechwycona grupa zaczyna się od tekstu zgodnego z podzbiorem wzorca zdefiniowanego dla tej przechwyconej grupy, można użyć asercji dodatniej o zerowej szerokości. Jeśli na przykład grupa przechwytywana pasuje do kolejnych znaków słów, możesz użyć asercji pozytywnej o zerowej szerokości, aby wymagać, by pierwszą literą była wielka litera.
W poniższym przykładzie użyto asercji o zerowej szerokości dodatniej, aby dopasować wyraz poprzedzający czasownik "is" w ciągu wejściowym.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"\b\w+(?=\sis\b)";
string[] inputs = { "The dog is a Malamute.",
"The island has beautiful birds.",
"The pitch missed home plate.",
"Sunday is a weekend day." };
foreach (string input in inputs)
{
Match match = Regex.Match(input, pattern);
if (match.Success)
Console.WriteLine($"'{match.Value}' precedes 'is'.");
else
Console.WriteLine($"'{input}' does not match the pattern.");
}
}
}
// The example displays the following output:
// 'dog' precedes 'is'.
// 'The island has beautiful birds.' does not match the pattern.
// 'The pitch missed home plate.' does not match the pattern.
// 'Sunday' precedes 'is'.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b\w+(?=\sis\b)"
Dim inputs() As String = {"The dog is a Malamute.", _
"The island has beautiful birds.", _
"The pitch missed home plate.", _
"Sunday is a weekend day."}
For Each input As String In inputs
Dim match As Match = Regex.Match(input, pattern)
If match.Success Then
Console.WriteLine("'{0}' precedes 'is'.", match.Value)
Else
Console.WriteLine("'{0}' does not match the pattern.", input)
End If
Next
End Sub
End Module
' The example displays the following output:
' 'dog' precedes 'is'.
' 'The island has beautiful birds.' does not match the pattern.
' 'The pitch missed home plate.' does not match the pattern.
' 'Sunday' precedes 'is'.
Wyrażenie \b\w+(?=\sis\b) regularne jest interpretowane, jak pokazano w poniższej tabeli.
| Wzorzec | opis |
|---|---|
\b |
Rozpocznij dopasowywanie na granicy wyrazu. |
\w+ |
Dopasowuje jeden lub więcej znaków słów. |
(?=\sis\b) |
Ustal, czy znaki wyrazu są śledzone przez znak odstępu i ciąg "is", który kończy się na granicy wyrazu. Jeśli tak, dopasowanie zakończy się pomyślnie. |
Asercja negatywna o zerowej szerokości
Następująca konstrukcja grupowania definiuje negatywną asercję o zerowej szerokości typu lookahead:
(?!
Subexpression)
W tym miejscu wyrażenie podrzędne jest dowolnym wzorcem wyrażenia regularnego. Aby dopasowanie zakończyło się pomyślnie, ciąg wejściowy nie powinien być zgodny ze wzorcem wyrażenia regularnego w podwyrażeniu, chociaż pasowany ciąg nie jest uwzględniony w wyniku dopasowania.
Asercja ujemna o zerowej szerokości jest zwykle używana na początku lub na końcu wyrażenia regularnego. Na początku wyrażenia regularnego można zdefiniować określony wzorzec, który nie powinien być dopasowany, gdy początek wyrażenia regularnego definiuje podobny, ale bardziej ogólny wzorzec do dopasowania. W tym przypadku często jest używana do ograniczania wycofywania. Na końcu wyrażenia regularnego można zdefiniować wyrażenie podrzędne, które nie może wystąpić na końcu dopasowania.
W poniższym przykładzie zdefiniowano wyrażenie regularne, które używa asercji lookahead o zerowej szerokości na początku wyrażenia regularnego w celu dopasowania wyrazów, które nie zaczynają się od "un".
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"\b(?!un)\w+\b";
string input = "unite one unethical ethics use untie ultimate";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
Console.WriteLine(match.Value);
}
}
// The example displays the following output:
// one
// ethics
// use
// ultimate
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b(?!un)\w+\b"
Dim input As String = "unite one unethical ethics use untie ultimate"
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
Console.WriteLine(match.Value)
Next
End Sub
End Module
' The example displays the following output:
' one
' ethics
' use
' ultimate
Wyrażenie \b(?!un)\w+\b regularne jest interpretowane, jak pokazano w poniższej tabeli.
| Wzorzec | opis |
|---|---|
\b |
Rozpocznij dopasowywanie na granicy wyrazu. |
(?!un) |
Sprawdź, czy następne dwa znaki to "un". Jeśli tak nie jest, możliwe jest dopasowanie. |
\w+ |
Dopasowuje jeden lub więcej znaków słów. |
\b |
Zakończ dopasowanie na granicy wyrazu. |
W poniższym przykładzie zdefiniowano wyrażenie regularne, które używa asercji lookahead o zerowej szerokości na końcu wyrażenia regularnego w celu dopasowania wyrazów, które nie kończą się znakiem interpunkcyjnym.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"\b\w+\b(?!\p{P})";
string input = "Disconnected, disjointed thoughts in a sentence fragment.";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine(match.Value);
}
}
// The example displays the following output:
// disjointed
// thoughts
// in
// a
// sentence
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b\w+\b(?!\p{P})"
Dim input As String = "Disconnected, disjointed thoughts in a sentence fragment."
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(match.Value)
Next
End Sub
End Module
' The example displays the following output:
' disjointed
' thoughts
' in
' a
' sentence
Wyrażenie \b\w+\b(?!\p{P}) regularne jest interpretowane, jak pokazano w poniższej tabeli.
| Wzorzec | opis |
|---|---|
\b |
Rozpocznij dopasowywanie na granicy wyrazu. |
\w+ |
Dopasowuje jeden lub więcej znaków słów. |
\b |
Zakończ dopasowanie na granicy wyrazu. |
\p{P}) |
Jeśli następny znak nie jest symbolem interpunkcyjnym (takim jak kropka lub przecinek), dopasowanie powiedzie się. |
Asercja dodatnia o zerowej szerokości
Następująca konstrukcja grupowania definiuje asercję pozytywną o zerowej długości.
(?<=
Subexpression)
W tym miejscu wyrażenie podrzędne jest dowolnym wzorcem wyrażenia regularnego. Aby dopasowanie zakończyło się powodzeniem, podwyrażenie musi występować w ciągu wejściowym na lewo od bieżącej pozycji, chociaż subexpression nie jest uwzględniane w wyniku dopasowania. Asercja pozytywna o zerowej szerokości patrzenia wstecz nie powoduje backtrackingu.
Asercji dodatnich o zerowej szerokości są zwykle używane na początku wyrażeń regularnych. Zdefiniowany wzorzec jest warunkiem wstępnym dopasowania, chociaż nie jest częścią wyniku dopasowania.
Na przykład poniższy przykład pasuje do dwóch ostatnich cyfr roku xxi wieku (czyli wymaga, aby cyfry "20" poprzedzały dopasowany ciąg).
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string input = "2010 1999 1861 2140 2009";
string pattern = @"(?<=\b20)\d{2}\b";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine(match.Value);
}
}
// The example displays the following output:
// 10
// 09
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "2010 1999 1861 2140 2009"
Dim pattern As String = "(?<=\b20)\d{2}\b"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(match.Value)
Next
End Sub
End Module
' The example displays the following output:
' 10
' 09
Wzorzec (?<=\b20)\d{2}\b wyrażenia regularnego jest interpretowany, jak pokazano w poniższej tabeli.
| Wzorzec | opis |
|---|---|
\d{2} |
Dopasuj dwie cyfry dziesiętne. |
(?<=\b20) |
Kontynuuj dopasowanie, jeśli dwie cyfry dziesiętne są poprzedzone cyframi dziesiętnymi "20" na granicy wyrazu. |
\b |
Zakończ dopasowanie na granicy wyrazu. |
Asercja dodatnia o zerowej szerokości jest również używana do ograniczania wycofywania, gdy ostatni znak lub znaki w przechwyconej grupie muszą być podzbiorem znaków pasujących do wzorca wyrażenia regularnego tej grupy. Jeśli na przykład grupa przechwytuje wszystkie kolejne znaki słów, możesz użyć asercji lookbehind o zerowej szerokości, aby wymagać, aby ostatni znak był alfabetyczny.
Asercja ujemna o zerowej szerokości
Następująca konstrukcja grupowania definiuje negatywną asercję o zerowej szerokości lookbehind:
(?<!
Subexpression)
W tym miejscu wyrażenie podrzędne jest dowolnym wzorcem wyrażenia regularnego. Aby dopasowanie zakończyło się pomyślnie, podwyrażenie nie może występować w ciągu wejściowym po lewej stronie bieżącego położenia. Jednak żadne podciągi, które nie są zgodne z subexpression, nie są uwzględnione w wyniku dopasowania.
Asercje negatywne wsteczne o zerowej szerokości są zazwyczaj używane na początku wyrażeń regularnych. Zdefiniowany wzorzec wyklucza dopasowanie w poniższym ciągu. Są one również używane do ograniczania wycofywania, gdy ostatni znak lub znaki w przechwyconej grupie nie mogą być co najmniej jednym znakiem zgodnym ze wzorcem wyrażenia regularnego tej grupy. Jeśli na przykład grupa przechwytuje wszystkie kolejne znaki wyrazów, możesz użyć asercji dodatniej o zerowej szerokości, aby wymagać, aby ostatni znak nie był podkreślenia (_).
Poniższy przykład jest zgodny z datą dowolnego dnia tygodnia, który nie jest weekendem (czyli nie jest to ani sobota, ani niedziela).
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string[] dates = { "Monday February 1, 2010",
"Wednesday February 3, 2010",
"Saturday February 6, 2010",
"Sunday February 7, 2010",
"Monday, February 8, 2010" };
string pattern = @"(?<!(Saturday|Sunday) )\b\w+ \d{1,2}, \d{4}\b";
foreach (string dateValue in dates)
{
Match match = Regex.Match(dateValue, pattern);
if (match.Success)
Console.WriteLine(match.Value);
}
}
}
// The example displays the following output:
// February 1, 2010
// February 3, 2010
// February 8, 2010
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim dates() As String = {"Monday February 1, 2010", _
"Wednesday February 3, 2010", _
"Saturday February 6, 2010", _
"Sunday February 7, 2010", _
"Monday, February 8, 2010"}
Dim pattern As String = "(?<!(Saturday|Sunday) )\b\w+ \d{1,2}, \d{4}\b"
For Each dateValue As String In dates
Dim match As Match = Regex.Match(dateValue, pattern)
If match.Success Then
Console.WriteLine(match.Value)
End If
Next
End Sub
End Module
' The example displays the following output:
' February 1, 2010
' February 3, 2010
' February 8, 2010
Wzorzec (?<!(Saturday|Sunday) )\b\w+ \d{1,2}, \d{4}\b wyrażenia regularnego jest interpretowany, jak pokazano w poniższej tabeli.
| Wzorzec | opis |
|---|---|
\b |
Rozpocznij dopasowywanie na granicy wyrazu. |
\w+ |
Dopasuj co najmniej jeden znak wyrazu, po którym następuje znak odstępu. |
\d{1,2}, |
Dopasuj jedną lub dwie cyfry dziesiętne, po których następuje znak odstępu i przecinek. |
\d{4}\b |
Dopasuj cztery cyfry dziesiętne i zakończ dopasowanie na granicy wyrazu. |
(?<!(Saturday|Sunday) ) |
Jeśli dopasowanie jest poprzedzone czymś innym niż ciągi "Sobota" lub "Niedziela", po którym następuje spacja, dopasowanie zakończy się pomyślnie. |
Grupy atomowe
Następująca konstrukcja grupowania reprezentuje grupę atomową (znaną w niektórych innych aparatach wyrażeń regularnych jako podwyrażenie niepowracające, atomowe podwyrażenie lub podwyrażenie tylko raz).
(?>
Subexpression)
W tym miejscu wyrażenie podrzędne jest dowolnym wzorcem wyrażenia regularnego.
Zwykle jeśli wyrażenie regularne zawiera opcjonalny lub alternatywny wzorzec dopasowania, a dopasowanie nie powiedzie się, silnik wyrażeń regularnych może rozgałęziać się w wielu kierunkach, aby dopasować ciąg wejściowy do wzorca. Jeśli dopasowanie nie zostanie znalezione, gdy przyjmuje pierwszą gałąź, aparat wyrażeń regularnych może cofnąć się do punktu, w którym dokonał pierwszego dopasowania, i spróbować dopasować przy użyciu drugiej gałęzi. Ten proces może być kontynuowany, dopóki wszystkie gałęzie nie zostały wypróbowane.
Konstrukcja (?>języka podwyrażenia) wyłącza wycofywanie. Silnik wyrażeń regularnych dopasuje jak najwięcej znaków, jak to możliwe, w ciągu wejściowym. Jeśli nie będzie możliwe żadne dalsze dopasowanie, nie nastąpi cofnięcie w celu próby dopasowania alternatywnego wzorca. (Oznacza to, że podwyrażenie pasuje tylko do ciągów, które byłyby dopasowane przez samo podwyrażenie; nie próbuje dopasować ciągu na podstawie podwyrażenia i wszystkich podwyrażeń, które za nim następują.)
Ta opcja jest zalecana, jeśli wiesz, że wycofywanie nie powiedzie się. Zapobieganie wykonywaniu niepotrzebnych wyszukiwań przez aparat wyrażeń regularnych zwiększa wydajność.
W poniższym przykładzie pokazano, jak grupa atomowa wpływa na wyniki dopasowania wzorca. Wyrażenie regularne z wycofywaniem pomyślnie dopasowuje się do serii powtarzających się znaków, po których następuje jeszcze jedno wystąpienie tego samego znaku na granicy wyrazu, ale wyrażenie regularne bez wycofywania nie daje wyniku.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string[] inputs = { "cccd.", "aaad", "aaaa" };
string back = @"(\w)\1+.\b";
string noback = @"(?>(\w)\1+).\b";
foreach (string input in inputs)
{
Match match1 = Regex.Match(input, back);
Match match2 = Regex.Match(input, noback);
Console.WriteLine($"{input}: ");
Console.Write(" Backtracking : ");
if (match1.Success)
Console.WriteLine(match1.Value);
else
Console.WriteLine("No match");
Console.Write(" Nonbacktracking: ");
if (match2.Success)
Console.WriteLine(match2.Value);
else
Console.WriteLine("No match");
}
}
}
// The example displays the following output:
// cccd.:
// Backtracking : cccd
// Nonbacktracking: cccd
// aaad:
// Backtracking : aaad
// Nonbacktracking: aaad
// aaaa:
// Backtracking : aaaa
// Nonbacktracking: No match
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim inputs() As String = {"cccd.", "aaad", "aaaa"}
Dim back As String = "(\w)\1+.\b"
Dim noback As String = "(?>(\w)\1+).\b"
For Each input As String In inputs
Dim match1 As Match = Regex.Match(input, back)
Dim match2 As Match = Regex.Match(input, noback)
Console.WriteLine("{0}: ", input)
Console.Write(" Backtracking : ")
If match1.Success Then
Console.WriteLine(match1.Value)
Else
Console.WriteLine("No match")
End If
Console.Write(" Nonbacktracking: ")
If match2.Success Then
Console.WriteLine(match2.Value)
Else
Console.WriteLine("No match")
End If
Next
End Sub
End Module
' The example displays the following output:
' cccd.:
' Backtracking : cccd
' Nonbacktracking: cccd
' aaad:
' Backtracking : aaad
' Nonbacktracking: aaad
' aaaa:
' Backtracking : aaaa
' Nonbacktracking: No match
Wyrażenie regularne bez cofania (?>(\w)\1+).\b jest zdefiniowane, jak pokazano w poniższej tabeli.
| Wzorzec | opis |
|---|---|
(\w) |
Dopasuj pojedynczy znak wyrazu i przypisz go do pierwszej grupy przechwytywania. |
\1+ |
Dopasuj wartość pierwszego przechwyconego podciągu jeden lub więcej razy. |
. |
Dopasuj dowolny znak. |
\b |
Zakończ dopasowanie na granicy wyrazu. |
(?>(\w)\1+) |
Dopasuj jedno lub więcej wystąpień zduplikowanego znaku słownego, ale nie cofaj się, aby dopasować ostatni znak znajdujący się na granicy wyrazu. |
Konstrukcje grupowania i obiekty wyrażeń regularnych
Podciągi dopasowane przez grupę przechwytywania wyrażeń regularnych są reprezentowane przez obiekty System.Text.RegularExpressions.Group, które można uzyskać z obiektu System.Text.RegularExpressions.GroupCollection zwracanego przez właściwość Match.Groups. Obiekt GroupCollection jest wypełniany w następujący sposób:
- Pierwszy Group obiekt w kolekcji (obiekt o indeksie zero) reprezentuje całe dopasowanie.
- Następny zestaw Group obiektów reprezentuje grupy przechwytywania nienazwanych (numerowanych). Są one wyświetlane w kolejności, w której są zdefiniowane w wyrażeniu regularnym od lewej do prawej. Wartości indeksu tych grup wahają się od 1 do liczby nienazwanych grup rejestrowania w kolekcji. Indeks określonej grupy jest równoważny jej numerowanemu odwołaniu wstecz. Aby uzyskać więcej informacji na temat odwołań wstecznych, zobacz Konstrukcje odwołań wstecznych.
- Końcowy zestaw Group obiektów reprezentuje nazwane grupy przechwytywania. Są one wyświetlane w kolejności, w której są zdefiniowane w wyrażeniu regularnym od lewej do prawej. Wartość indeksu pierwszej nazwanej grupy przechwytywania jest większa niż indeks ostatniej grupy przechwytywania bez nazwy. Jeśli w wyrażeniu regularnym nie ma żadnych nienazwanych grup przechwytywania, wartość indeksu pierwszej nazwanej grupy przechwytywania jest jedną.
Jeśli zastosujesz kwantyfikator do grupy przechwytywania, właściwości odpowiedniego obiektu Group, Capture.Value, Capture.Index, i Capture.Length odzwierciedlają ostatni ciąg przechwycony przez grupę przechwytywania. Można pobrać pełny zestaw podciągów z obiektu CaptureCollection, które są przechwycone przez grupy posiadające kwantyfikatory, zwracany przez właściwość Group.Captures.
W poniższym przykładzie wyjaśniono relację między obiektami Group i Capture .
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"(\b(\w+)\W+)+";
string input = "This is a short sentence.";
Match match = Regex.Match(input, pattern);
Console.WriteLine($"Match: '{match.Value}'");
for (int ctr = 1; ctr < match.Groups.Count; ctr++)
{
Console.WriteLine($" Group {ctr}: '{match.Groups[ctr].Value}'");
int capCtr = 0;
foreach (Capture capture in match.Groups[ctr].Captures)
{
Console.WriteLine($" Capture {capCtr}: '{capture.Value}'");
capCtr++;
}
}
}
}
// The example displays the following output:
// Match: 'This is a short sentence.'
// Group 1: 'sentence.'
// Capture 0: 'This '
// Capture 1: 'is '
// Capture 2: 'a '
// Capture 3: 'short '
// Capture 4: 'sentence.'
// Group 2: 'sentence'
// Capture 0: 'This'
// Capture 1: 'is'
// Capture 2: 'a'
// Capture 3: 'short'
// Capture 4: 'sentence'
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "(\b(\w+)\W+)+"
Dim input As String = "This is a short sentence."
Dim match As Match = Regex.Match(input, pattern)
Console.WriteLine("Match: '{0}'", match.Value)
For ctr As Integer = 1 To match.Groups.Count - 1
Console.WriteLine(" Group {0}: '{1}'", ctr, match.Groups(ctr).Value)
Dim capCtr As Integer = 0
For Each capture As Capture In match.Groups(ctr).Captures
Console.WriteLine(" Capture {0}: '{1}'", capCtr, capture.Value)
capCtr += 1
Next
Next
End Sub
End Module
' The example displays the following output:
' Match: 'This is a short sentence.'
' Group 1: 'sentence.'
' Capture 0: 'This '
' Capture 1: 'is '
' Capture 2: 'a '
' Capture 3: 'short '
' Capture 4: 'sentence.'
' Group 2: 'sentence'
' Capture 0: 'This'
' Capture 1: 'is'
' Capture 2: 'a'
' Capture 3: 'short'
' Capture 4: 'sentence'
Wzorzec (\b(\w+)\W+)+ wyrażenia regularnego wyodrębnia poszczególne wyrazy z ciągu. Definicję tego wyrażenia pokazano w poniższej tabeli.
| Wzorzec | opis |
|---|---|
\b |
Rozpocznij dopasowywanie na granicy wyrazu. |
(\w+) |
Dopasowuje jeden lub więcej znaków słów. Razem te znaki tworzą wyraz. Jest to druga grupa przechwytywania. |
\W+ |
Dopasuj jeden lub więcej znaków innych niż litery lub cyfry. |
(\b(\w+)\W+) |
Dopasuj wzorzec składający się z jednego lub więcej znaków słownych, po których następują jeden lub więcej znaków niesłownych, występujący co najmniej raz. Jest to pierwsza grupa przechwytywania. |
Druga grupa przechwytywania dopasowuje się do każdego słowa zdania. Pierwsza grupa przechwytująca dopasowuje każdy wyraz wraz ze znakiem interpunkcyjnym i odstępem, które następują po tym słowie. Obiekt Group , którego indeks ma wartość 2, zawiera informacje o tekście dopasowanym przez drugą grupę przechwytywania. Pełny zestaw wyrazów przechwyconych przez grupę przechwytywania jest dostępny z obiektu CaptureCollection, który zwrócony jest przez właściwość Group.Captures.