Udostępnij za pośrednictwem


Konstrukcje grupowania w wyrażeniach regularnych

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 podyrażenie powtarzające 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 podrażenie w ciągu zwracanym przez Regex.Replace metody 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 wskazuje, czy przechwytują, czy nie są one hermetyzowane.

Konstrukcja grupująca Przechwytywanie lub brak hermetyzacji
Dopasowane podrażenia Przechwytywanie
Nazwane dopasowane podrażenia Przechwytywanie
Równoważenie definicji grup Przechwytywanie
Grupy niezwiązane z hermetyzowaniem Brak hermetyzacji
Opcje grupy Brak hermetyzacji
Asercja dodatnia o zerowej szerokości Brak hermetyzacji
Asercja ujemna o zerowej szerokości Brak hermetyzacji
Asercja dodatnia o zerowej szerokości Brak hermetyzacji
Asercja ujemna o zerowej szerokości Brak hermetyzacji
Grupy niepodzielne Brak hermetyzacji

Aby uzyskać informacje na temat grup i modelu obiektów wyrażeń regularnych, zobacz Grupowanie konstrukcji i obiektów wyrażeń regularnych.

Dopasowane podrażenia

Następująca konstrukcja grupowania przechwytuje dopasowane podwyrażenie:

(Subexpression )

W tym miejscu wyrażenie podrzędne jest dowolnym prawidłowym wzorcem wyrażenia regularnego. Przechwytywanie używające nawiasów są automatycznie numerowane od lewej do prawej w oparciu o kolejność nawiasów otwierających w wyrażeniu regularnym, począwszy od 1. Jednak nazwane grupy przechwytywania są zawsze uporządkowane jako ostatnie po nienazwanych grupach przechwytywania. Przechwycenie numerowane 0 jest tekstem dopasowanym przez cały wzorzec wyrażenia regularnego.

Uwaga

Domyślnie (element języka podwyrażenia przechwytuje dopasowane podwyrażenie) . RegexOptions Jeśli jednak parametr 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 artykułu), dopasowane podwyrażenie nie jest przechwytywane.

Dostęp do przechwyconych grup można uzyskać na cztery sposoby:

  • Używając konstrukcji wnioskowania wstecznego w wyrażeniu regularnym. Dopasowane podwyrażenie jest przywoływane w tym samym wyrażeniu regularnym przy użyciu numeru składni\, gdzie liczba jest liczbą porządkową przechwyconego podwyrażenia.

  • Używając konstrukcji nazwanego wycofywania w wyrażeniu regularnym. Dopasowane podwyrażenie jest przywoływane w tym samym wyrażeniu regularnym przy użyciu nazwy składni\k<, gdzie nazwa jest nazwą> grupy przechwytywania lub \k<liczby>, 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, zobacz Nazwane dopasowane podrażenia w dalszej części tego tematu.

  • Używając sekwencji zastępczej $numeru w Regex.Replace wywołaniu metody lub Match.Result , gdzie liczba jest numerem porządkowym przechwyconego podwyrażenia.

  • Programowo przy użyciu GroupCollection obiektu zwróconego Match.Groups przez właściwość . Element członkowski na pozycji zero w kolekcji reprezentuje całe dopasowanie wyrażenia regularnego. Każdy kolejny element członkowski reprezentuje dopasowane podrażenie. 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. Dwa przechwytywane grupy wyrażeń regularnych reprezentują dwa wystąpienia zduplikowanego słowa. Drugie wystąpienie jest przechwytywane, aby zgłosić swoją 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 '{0}' found at positions {1} and {2}.",
                           match.Groups[1].Value, match.Groups[1].Index, 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 co najmniej jeden znak słowa. Jest to pierwsza grupa przechwytywania.
\s Dopasowuje znak odstępu.
(\1) Dopasuj ciąg 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 podrażenia

Następująca konstrukcja grupowania przechwytuje dopasowane podwyrażenie i umożliwia dostęp do niej według nazwy lub liczby:

(?<name>subexpression)

or:

(?'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 wycofywania w wyrażeniu regularnym. Dopasowane podwyrażenie jest przywoływane w tym samym wyrażeniu regularnym przy użyciu nazwy> składni\k<, gdzie nazwa jest nazwą przechwyconego podwyrażenia.

  • Używając konstrukcji wnioskowania wstecznego w wyrażeniu regularnym. Dopasowane podwyrażenie jest przywoływane w tym samym wyrażeniu regularnym przy użyciu numeru składni\, gdzie liczba jest liczbą porządkową przechwyconego podwyrażenia. Nazwane dopasowane podrażenia są numerowane kolejno od lewej do prawej po dopasowanych podexpressionach.

  • Używając sekwencji zastępczej ${nazwy} w Regex.Replace wywołaniu metody lub Match.Result , gdzie nazwa jest nazwą przechwyconego podwyrażenia.

  • Używając sekwencji zastępczej $numeru w Regex.Replace wywołaniu metody lub Match.Result , gdzie liczba jest numerem porządkowym przechwyconego podwyrażenia.

  • Programowo przy użyciu GroupCollection obiektu zwróconego Match.Groups przez właściwość . Element członkowski na pozycji zero w kolekcji reprezentuje całe dopasowanie wyrażenia regularnego. Każdy kolejny element członkowski reprezentuje dopasowane podraż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. Wyrażenie ((?<One>abc)\d+)?(?<Two>xyz)(.*) regularne tworzy następujące przechwytywanie grup 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)
100 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 podrażenia: duplicateWord, który reprezentuje zduplikowane słowo i nextWord, który reprezentuje słowo, które następuje po zduplikowanym słowie.

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 '{0}' at position {1} is followed by '{2}'.",
                           match.Groups["duplicateWord"].Value, match.Groups["duplicateWord"].Index,
                           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 co najmniej jeden znak słowa. Nadaj tej grupie duplicateWordprzechwytywania nazwę .
\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 co najmniej jeden znak słowa. Nadaj tej grupie nextWordprzechwytywania nazwę .

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ść Group obiektu 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 co najmniej jeden znak cyfry. Druga digit nazwana grupa przechwytuje zero lub jedno wystąpienie co najmniej jednego znaku cyfry. Jak pokazano w danych wyjściowych z przykładu, jeśli druga grupa przechwytywania pomyślnie pasuje do tekstu, wartość tego tekstu definiuje wartość Group obiektu. 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: {0}", m.Value);
            for (int grpCtr = 1; grpCtr < m.Groups.Count; grpCtr++) {
               Group grp = m.Groups[grpCtr];
               Console.WriteLine("Group {0}: {1}", grpCtr, grp.Value);
               for (int capCtr = 0; capCtr < grp.Captures.Count; capCtr++)
                  Console.WriteLine("   Capture {0}: {1}", 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 nazwanej digit grupy.
\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 nazwanej digit grupy.

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)

or:

(?'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 równoważenia usuwa definicję name2 i przechowuje interwał między name2 i name1 w nazwie1. Jeśli żadna grupa name2 nie jest zdefiniowana, dopasowanie wycofywania. Ponieważ usunięcie ostatniej definicji name2 ujawnia poprzednią definicję name2, ta konstrukcja umożliwia użycie stosu przechwytywania dla nazwy grupy2 jako licznika do śledzenia zagnieżdżonych konstrukcji, takich jak nawiasy lub nawiasy otwierające i zamykające.

Definicja grupy równoważenia używa nazwy 2 jako stosu. Początkowy znak 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 kwadratowe lewego i prawego kąta (<>) 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 wypychany do kolekcji Open przechwytywania grupy, a każdy przechwycony nawias prawego kąta jest wypychany do kolekcji przechwytywania Close grupy. Definicja grupy równoważenia gwarantuje, że dla każdego nawiasu kątowego po lewej stronie istnieje pasujący nawias kątowy. Jeśli tak nie jest, końcowa podwzorca , jest obliczana tylko wtedy, (?(Open)(?!))gdy Open grupa nie jest pusta (i dlatego, jeśli wszystkie zagnieżdżone konstrukcje nie zostały zamknięte). Jeśli końcowa podwzorca jest oceniana, dopasowanie kończy się niepowodzeniem, ponieważ (?!) podwzorca 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: \"{0}\" \nMatch: \"{1}\"", input, m);
         int grpCtr = 0;
         foreach (Group grp in m.Groups)
         {
            Console.WriteLine("   Group {0}: {1}", grpCtr, grp.Value);
            grpCtr++;
            int capCtr = 0;
            foreach (Capture cap in grp.Captures)
            {
                Console.WriteLine("      Capture {0}: {1}", 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
^ Zacznij od początku ciągu.
[^<>]* Dopasuj zero lub więcej znaków, które nie są nawiasami kwadratowymi 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 kwadratowymi lewego lub prawego kąta.
((?'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ą nawiasami kwadratowymi lewego lub prawego kąta. Jest to druga grupa przechwytywania.
(?'Close-Open'>) Dopasuj nawias kątowy do prawej, przypisz podciąg między Open grupą a bieżącą grupą Close i usuń definicję Open grupy.
[^<>]* Dopasuj zero lub więcej wystąpień żadnego znaku, który nie jest ani lewy, ani prawy nawias kątowy.
((?'Close-Open'>)[^<>]*)+ Dopasuj jedno lub więcej wystąpień nawiasu kątowego prawego, po którym następuje zero lub więcej wystąpień dowolnego znaku, który nie jest ani lewy, ani prawy nawias kątowy. Podczas dopasowywania nawiasu kątowego przypisz podciąg między Open grupą a bieżącą grupą do Close grupy i usuń definicję Open grupy. 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 nawiasu kątowego usuń definicję Open grupy i przypisz podciąg między Open grupą a bieżącą grupą Close do grupy. Jest to pierwsza grupa przechwytywania.
(?(Open)(?!)) Open Jeśli grupa istnieje, porzuć dopasowanie, jeśli można dopasować pusty ciąg, ale nie zwiększaj pozycji aparatu 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.
$ Dopasowuje koniec ciągu wejściowego.

Końcowe podrażenie, , wskazuje, (?(Open)(?!))czy konstrukcje zagnieżdżenia w ciągu wejściowym są prawidłowo zrównoważone (na przykład, czy każdy lewy nawias kątowy jest dopasowany przez nawias kątowy po prawej stronie). Używa dopasowywania warunkowego w oparciu o prawidłową przechwyconą grupę; Aby uzyskać więcej informacji, zobacz Konstrukcje zmiany. Open Jeśli grupa jest zdefiniowana, aparat wyrażeń regularnych próbuje dopasować podexpression (?!) w ciągu wejściowym. Grupa powinna być zdefiniowana Open tylko wtedy, gdy konstrukcje zagnieżdżenia są niezrównoważone. 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 nawiasu niekątnego przed nawiasem kwadratowym po lewej stronie; wyszukuje brak dopasowań.
3 (((?'Open'<) Pasuje do lewego nawiasu kątowego w ciągu "<abc>" i przypisuje go do Open grupy.
100 [^<>]* Pasuje do "abc".
5 )+ "<abc" to wartość drugiej przechwyconej grupy.

Następny znak w ciągu wejściowym nie jest nawiasem kwadratowym lewego kąta, więc aparat wyrażeń regularnych nie zapętla się z powrotem do (?'Open'<)[^<>]*) podwzorcy.
6 ((?'Close-Open'>) Pasuje do prawego nawiasu kątowego w ciągu "<abc", przypisuje wartość "abc>", czyli podciąg między Open grupą a prawym nawiasem kątowym, do Close grupy i usuwa bieżącą wartość ("<") Open grupy, 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 wraca do (((?'Open'<) podwzorcy.
10 (((?'Open'<) Pasuje do lewego nawiasu kątowego w ciągu "<mno" i przypisuje go do Open grupy. Jego Group.Captures kolekcja ma teraz pojedynczą wartość "<".
11 [^<>]* Pasuje do "mno".
12 )+ "<mno" to wartość drugiej przechwyconej grupy.

Następny znak w ciągu wejściowym to lewy nawias kątowy, więc aparat wyrażeń regularnych wraca do (?'Open'<)[^<>]*) podwzorca.
13 (((?'Open'<) Pasuje do lewego nawiasu kątowego w ciągu "<xyz>" i przypisuje go do Open grupy. Kolekcja Group.Captures Open grupy zawiera teraz dwa przechwytywane: lewy nawias kątowy z "<mno" i lewy nawias kątowy z "<xyz>".
14 [^<>]* Pasuje do "xyz".
15 )+ "<xyz" to wartość drugiej przechwyconej grupy.

Następny znak w ciągu wejściowym nie jest nawiasem kwadratowym lewego kąta, więc aparat wyrażeń regularnych nie zapętla się z powrotem do (?'Open'<)[^<>]*) podwzorcy.
16 ((?'Close-Open'>) Pasuje do prawego nawiasu kątowego w ciągu "<xyz>". "xyz", przypisuje podciąg między Open grupą a nawiasem prawym kątem do Close grupy i usuwa bieżącą wartość Open grupy. Wartość poprzedniego przechwytywania (lewy nawias kątowy w< "mno") staje się bieżącą wartością Open grupy. Kolekcja Captures Open grupy zawiera teraz pojedyncze przechwytywanie, lewy nawias kątowy z "<xyz>".
17 [^<>]* Wyszukuje znaki nawiasu niekątnego; wyszukuje brak dopasowań.
18 )+ Wartość trzeciej przechwyconej grupy to ">".

Następny znak w ciągu wejściowym jest nawiasem kątowym po prawej stronie, więc aparat wyrażeń regularnych wraca do ((?'Close-Open'>)[^<>]*) podwzorcy.
19 ((?'Close-Open'>) Pasuje do końcowego nawiasu kątowego w nawiasie "xyz>>", przypisuje do grupy wartość "mno<xyz>" (podciąg między Open grupą a nawiasem prawym kątem) Close i usuwa bieżącą wartość Open grupy. Grupa jest teraz pusta Open .
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 prostym, więc aparat 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 nawiasem kwadratowym lewego kąta, więc aparat wyrażeń regularnych nie zapętla się z powrotem do (((?'Open'<) podwzorcy.
23 (?(Open)(?!)) Grupa nie jest zdefiniowana Open , więc nie podjęto próby dopasowania.
24 $ Pasuje do końca ciągu wejściowego.

Grupy niezwiązane z hermetyzowaniem

Następująca konstrukcja grupowania nie przechwytuje podciągów pasujących do podwyrażenia:

(?:subexpression)

W tym miejscu wyrażenie podrzędne jest dowolnym prawidłowym wzorcem wyrażenia regularnego. Nieuwzwolona konstrukcja grupy jest zwykle używana, gdy kwantyfikator jest stosowany do grupy, ale podciągy przechwycone przez grupę nie są interesujące.

Uwaga

Jeśli wyrażenie regularne zawiera zagnieżdżone konstrukcje grupowania, zewnętrzna konstrukcja grupy nie zawiera konstrukcji grupy zagnieżdżonej.

W poniższym przykładzie pokazano wyrażenie regularne, które zawiera grupy niepochodzą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: {0}", match.Value);
      for (int ctr = 1; ctr < match.Groups.Count; ctr++)
         Console.WriteLine("   Group {0}: {1}", 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 (?:\b(?:\w+)\W*)+\. regularne pasuje do zdania, które jest przerywane 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 Rozpoczyna dopasowanie na granicy wyrazu.
(?:\w+) Dopasowuje co najmniej jeden znak słowa. Nie przypisuj dopasowanego tekstu do przechwyconej grupy.
\W* Dopasuj zero lub więcej znaków innych niż wyrazy.
(?:\b(?:\w+)\W*)+ Dopasuj wzorzec co najmniej jednego znaku słowa rozpoczynającego się od granicy wyrazu, po którym następuje zero lub więcej znaków innych niż słowa, co najmniej jeden raz. Nie przypisuj dopasowanego tekstu do przechwyconej grupy.
\. Dopasuj kropkę.

Opcje grupy

Następująca konstrukcja grupowania ma zastosowanie lub wyłącza określone opcje w podrażeniu:

(?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 bez uwzględniania wielkości liter i wyłącza tryb jednowierszowy. 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 (?imnsx-imnsx) regularnym przy użyciu konstrukcji języka.

Konstrukcja opcji grupy nie jest grupą przechwytywania. Oznacza to, że chociaż każda część ciągu przechwycona przez podwyrażenie jest uwzględniona w dopasowaniu, nie jest uwzględniana w przechwyconej grupie ani nie jest używana do wypełniania GroupCollection obiektu.

Na przykład wyrażenie \b(?ix: d \w+)\s regularne w poniższym przykładzie używa wbudowanych opcji w konstrukcji grupowania, aby umożliwić dopasowywanie bez uwzględniania wielkości liter i ignorowanie białych znaków wzorca w identyfikowaniu wszystkich wyrazów rozpoczynających się literą "d". Wyrażenie regularne jest definiowane, jak pokazano w poniższej tabeli.

Wzorzec opis
\b Rozpoczyna dopasowanie na granicy wyrazu.
(?ix: d \w+) W przypadku dopasowywania bez uwzględniania wielkości liter i ignorowania białych znaków w tym wzorcu dopasowuje znak "d", po którym następuje co najmniej jeden znak słowa.
\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("'{0}// found at index {1}.", match.Value, 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.      

Asercja dodatnia o zerowej szerokości

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ż dopasowane podciąg nie jest uwzględniany w wyniku dopasowania. Asercja dodatnia o zerowej szerokości nie jest wycofywania.

Zazwyczaj na końcu wzorca wyrażenia regularnego znajduje się asercja dodatnia o zerowej szerokości. Definiuje on podciąg, który musi zostać znaleziony na końcu ciągu, aby dopasowanie wystąpiło, ale nie powinno być uwzględnione w dopasowaniu. Jest to również przydatne w przypadku zapobiegania nadmiernemu wycofywaniu. 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 przechwycenie grupy pasuje do kolejnych znaków wyrazów, możesz użyć asercji dodatniej o zerowej szerokości, aby wymagać, aby pierwszy znak był znakiem alfabetycznym wielkimi literami.

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("'{0}' precedes 'is'.", match.Value);
         else
            Console.WriteLine("'{0}' does not match the pattern.", input);
      }
   }
}
// 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 Rozpoczyna dopasowanie na granicy wyrazu.
\w+ Dopasowuje co najmniej jeden znak słowa.
(?=\sis\b) Ustal, czy znaki wyrazu są znakami odstępu i ciągiem "is", który kończy się na granicy wyrazu. Jeśli tak, dopasowanie zakończy się pomyślnie.

Asercja ujemna o zerowej szerokości

Następująca konstrukcja grupowania definiuje negatywną asercję 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 nie może być zgodny ze wzorcem wyrażenia regularnego w podraż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 Rozpoczyna dopasowanie na granicy wyrazu.
(?!un) Ustal, czy następne dwa znaki są "un". Jeśli tak nie jest, możliwe jest dopasowanie.
\w+ Dopasowuje co najmniej jeden znak słowa.
\b Kończy 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 Rozpoczyna dopasowanie na granicy wyrazu.
\w+ Dopasowuje co najmniej jeden znak słowa.
\b Kończy 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 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ę powodzeniem, podwyrażenie musi występować w ciągu wejściowym po lewej stronie bieżącej pozycji, chociaż subexpression nie jest uwzględniane w wyniku dopasowania. Asercja dodatnia o zerowej szerokości nie jest wycofana.

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ętnym "20" na granicy wyrazu.
\b Kończy 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 wszystkie podciągy, które nie są zgodne subexpression , nie są uwzględnione w wyniku dopasowania.

Asercja ujemna o zerowej szerokości jest zwykle używana 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 Rozpoczyna dopasowanie 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 niepodzielne

Następująca konstrukcja grupowania reprezentuje grupę niepodzieną (znaną w niektórych innych aparatach wyrażeń regularnych jako podwyrażenie niewzwiązane, niepodzielne wyrażenie podrzędne lub wyrażenie podrzędne 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ę, aparat wyrażeń regularnych może rozgałęzić 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 wykonać kopię zapasową lub cofnąć się do punktu, w którym zajęło pierwsze dopasowanie 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. Aparat wyrażeń regularnych będzie zgodny z dowolną liczbą znaków w ciągu wejściowym. Jeśli nie będzie możliwe żadne dalsze dopasowanie, nie będzie można cofnąć próby dopasowania alternatywnego wzorca. (Oznacza to, że podexpression pasuje tylko do ciągów, które byłyby dopasowane przez samo wyrażenie podrzędne; nie próbuje dopasować ciągu na podstawie podexpressionu i wszystkich podwyrażeń, które są zgodne z nim.)

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 niepodzielna modyfikuje wyniki dopasowania wzorca. Wyrażenie regularne wycofywania pomyślnie pasuje 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 nie jest zwracane.

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("{0}: ", 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 (?>(\w)\1+).\b nieobsługiwane 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 co najmniej raz.
. Dopasuj dowolny znak.
\b Zakończ dopasowanie na granicy wyrazu.
(?>(\w)\1+) Dopasuj co najmniej jedno wystąpienie zduplikowanego znaku wyrazu, ale nie cofaj się w celu dopasowania ostatniego znaku na granicy wyrazu.

Konstrukcje grupowania i obiekty wyrażeń regularnych

Podciągy dopasowane przez grupę przechwytywania wyrażeń regularnych są reprezentowane przez System.Text.RegularExpressions.Group obiekty, które można pobrać z System.Text.RegularExpressions.GroupCollection obiektu zwracanego przez Match.Groups właściwość . 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 przechwytywania w kolekcji. (Indeks określonej grupy jest odpowiednikiem jego numerowanego wnioskowania wstecznego. Aby uzyskać więcej informacji na temat backreferences, zobacz Backreference Constructs (Konstrukcje backreference).
  • 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, odpowiednie Group właściwości obiektu Capture.Value, Capture.Indexi Capture.Length odzwierciedlają ostatni podciąg przechwycony przez grupę przechwytywania. Można pobrać pełny zestaw podciągów przechwyconych przez grupy, które mają kwantyfikatory z CaptureCollection obiektu zwracanego przez Group.Captures właściwość .

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: '{0}'", match.Value);
      for (int ctr = 1; ctr < match.Groups.Count; ctr++)
      {
         Console.WriteLine("   Group {0}: '{1}'", ctr, match.Groups[ctr].Value);
         int capCtr = 0;
         foreach (Capture capture in match.Groups[ctr].Captures)
         {
            Console.WriteLine("      Capture {0}: '{1}'", 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 Rozpoczyna dopasowanie na granicy wyrazu.
(\w+) Dopasowuje co najmniej jeden znak słowa. Razem te znaki tworzą wyraz. Jest to druga grupa przechwytywania.
\W+ Dopasuj jeden lub więcej znaków innych niż wyrazy.
(\b(\w+)\W+) Dopasuj wzorzec co najmniej jednego znaku słowa, po którym następuje jeden lub więcej znaków innych niż wyrazy. Jest to pierwsza grupa przechwytywania.

Druga grupa przechwytywania odpowiada każdemu słowu zdania. Pierwsza grupa przechwytywania pasuje do każdego wyrazu wraz z znakiem interpunkcyjnym i odstępem, który następuje po 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 CaptureCollection obiektu zwróconego Group.Captures przez właściwość .

Zobacz też