Delen via


Groeperingsconstructies in reguliere expressies

Met groepering worden de subexpressies van een reguliere expressie afgebakend en worden de subtekenreeksen van een invoertekenreeks vastgelegd. U kunt groeperingsconstructies gebruiken om het volgende te doen:

  • Komt overeen met een subexpressie die wordt herhaald in de invoertekenreeks.
  • Pas een kwantificator toe op een subexpressie met meerdere reguliere expressietaalelementen. Zie Kwantificatoren voor meer informatie over kwantificatoren.
  • Neem een subexpressie op in de tekenreeks die wordt geretourneerd door de Regex.Replace en Match.Result methoden.
  • Haal afzonderlijke subexpressies op uit de Match.Groups eigenschap en verwerk ze afzonderlijk van de overeenkomende tekst als geheel.

De volgende tabel bevat de groeperingsconstructies die worden ondersteund door de .NET-engine voor reguliere expressies en geeft aan of ze vastleggen of niet-inkapsering zijn.

Groeperingsconstructie Vastleggen of niet-inkapsering
Overeenkomende subexpressies Vastleggen
Benoemde overeenkomende subexpressies Vastleggen
Groepsdefinities verdelen Vastleggen
Niet-aaneengesloten groepen Niet-inkapsering
Groepsopties Niet-inkapsering
Positieve lookahead-asserties met nulbreedte Niet-inkapsering
Negatieve lookahead-asserties met nulbreedte Niet-inkapsering
Positieve lookbehind-asserties met nulbreedte Niet-inkapsering
Negatieve lookbehind-asserties met nulbreedte Niet-inkapsering
Atomische groepen Niet-inkapsering

Zie Groeperingsconstructies en reguliere expressieobjectobjecten voor informatie over groepen en het reguliere expressieobject.

Overeenkomende subexpressies

Met de volgende groeperingsconstructie wordt een overeenkomende subexpressie vastgelegd:

(subexpressie )

Hier is subexpressie een geldig patroon voor reguliere expressies. Opnamen die haakjes gebruiken, worden automatisch genummerd van links naar rechts op basis van de volgorde van de haakjes openen in de reguliere expressie, beginnend vanaf 1. Benoemde capture-groepen worden echter altijd als laatste geordend, na niet-benoemde capture-groepen. De opname met nummer 0 is de tekst die overeenkomt met het volledige reguliere expressiepatroon.

Notitie

Standaard legt het (subexpressietaalelement) de overeenkomende subexpressie vast. Maar als de RegexOptions parameter van een reguliere expressiepatroonkoppelingsmethode de RegexOptions.ExplicitCapture vlag bevat of als de n optie wordt toegepast op deze subexpressie (zie Groepsopties verderop in dit artikel), wordt de overeenkomende subexpressie niet vastgelegd.

U kunt op vier manieren toegang krijgen tot vastgelegde groepen:

  • Met behulp van de backreference-constructie binnen de reguliere expressie. De overeenkomende subexpressie wordt in dezelfde reguliere expressie verwezen met behulp van het syntaxisnummer\, waarbij getal het rangnummer is van de vastgelegde subexpressie.

  • Met behulp van de benoemde backreference-constructie binnen de reguliere expressie. De overeenkomende subexpressie wordt in dezelfde reguliere expressie verwezen met behulp van de syntaxisnaam\k<>, waarbij de naam de naam is van een vastleggende groep of \k<getal>, waarbij getal het rangnummer is van een vastleggende groep. Een vastleggende groep heeft een standaardnaam die identiek is aan het rangnummer. Zie Benoemde overeenkomende subexpressies verderop in dit onderwerp voor meer informatie.

  • Door de $nummervervangingsreeks in een Regex.Replace of Match.Result methode-aanroep te gebruiken, waarbij getal het rangnummer is van de vastgelegde subexpressie.

  • Programmatisch, met behulp van het GroupCollection object dat door de Match.Groups eigenschap wordt geretourneerd. Het lid op positie nul in de verzameling vertegenwoordigt de volledige overeenkomst met de reguliere expressie. Elk volgend lid vertegenwoordigt een overeenkomende subexpressie. Zie de sectie Groeperingsconstructies en reguliere expressieobjecten voor meer informatie.

In het volgende voorbeeld ziet u een reguliere expressie waarmee dubbele woorden in tekst worden geïdentificeerd. De twee vastleggende groepen van het reguliere expressiepatroon vertegenwoordigen de twee exemplaren van het gedupliceerde woord. Het tweede exemplaar wordt vastgelegd om de beginpositie in de invoertekenreeks te rapporteren.

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.

Het reguliere expressiepatroon is het volgende:

(\w+)\s(\1)\W

In de volgende tabel ziet u hoe het reguliere expressiepatroon wordt geïnterpreteerd.

Patroon Beschrijving
(\w+) Komt overeen met een of meer woordtekens. Dit is de eerste opnamegroep.
\s Overeenkomst met een spatieteken.
(\1) Komt overeen met de tekenreeks in de eerste vastgelegde groep. Dit is de tweede vastleggende groep. In het voorbeeld wordt deze toegewezen aan een vastgelegde groep, zodat de beginpositie van het dubbele woord kan worden opgehaald uit de Match.Index eigenschap.
\W Komt overeen met een niet-woordteken, inclusief spatie en leestekens. Dit voorkomt dat het reguliere expressiepatroon overeenkomt met een woord dat begint met het woord uit de eerste vastgelegde groep.

Benoemde overeenkomende subexpressies

Met de volgende groeperingsconstructie wordt een overeenkomende subexpressie vastgelegd en kunt u deze openen op naam of getal:

(?<name>subexpression)

of:

(?'name'subexpression)

Hier is de naam een geldige groepsnaam en subexpressie is een geldig patroon voor reguliere expressies. de naam mag geen leestekens bevatten en mag niet beginnen met een getal.

Notitie

Als de RegexOptions parameter van een reguliere expressiepatroonkoppelingsmethode de RegexOptions.ExplicitCapture vlag bevat of als de n optie wordt toegepast op deze subexpressie (zie Groepsopties verderop in dit onderwerp), is de enige manier om een subexpressie vast te leggen expliciet een naam voor het vastleggen van groepen.

U kunt op de volgende manieren toegang krijgen tot vastgelegde groepen:

  • Met behulp van de benoemde backreference-constructie binnen de reguliere expressie. Er wordt naar de overeenkomende subexpressie verwezen in dezelfde reguliere expressie met behulp van de syntaxisnaam\k<>, waarbij de naam de naam is van de vastgelegde subexpressie.

  • Met behulp van de backreference-constructie binnen de reguliere expressie. De overeenkomende subexpressie wordt in dezelfde reguliere expressie verwezen met behulp van het syntaxisnummer\, waarbij getal het rangnummer is van de vastgelegde subexpressie. Benoemde overeenkomende subexpressies worden opeenvolgend genummerd van links naar rechts na overeenkomende subexpressies.

  • Door de ${naamvervangingsreeks} in een Regex.Replace of Match.Result methode-aanroep te gebruiken, waarbij de naam de naam is van de vastgelegde subexpressie.

  • Door de $nummervervangingsreeks in een Regex.Replace of Match.Result methode-aanroep te gebruiken, waarbij getal het rangnummer is van de vastgelegde subexpressie.

  • Programmatisch, met behulp van het GroupCollection object dat door de Match.Groups eigenschap wordt geretourneerd. Het lid op positie nul in de verzameling vertegenwoordigt de volledige overeenkomst met de reguliere expressie. Elk volgend lid vertegenwoordigt een overeenkomende subexpressie. Benoemde vastgelegde groepen worden opgeslagen in de verzameling na genummerde vastgelegde groepen.

  • Programmatisch, door de naam van de subexpressie op te geven aan de indexeerfunctie van het object (in C#) of aan Item[] de GroupCollection eigenschap (in Visual Basic).

Een eenvoudig patroon voor reguliere expressies illustreert hoe genummerde (niet-benoemde) en benoemde groepen via een programma kunnen worden verwezen of met behulp van de syntaxis van de reguliere expressietaal. De reguliere expressie ((?<One>abc)\d+)?(?<Two>xyz)(.*) produceert de volgende opnamegroepen op getal en op naam. De eerste vastleggende groep (getal 0) verwijst altijd naar het hele patroon. (Benoemde groepen worden altijd als laatste geordend.)

Aantal Naam Patroon
0 0 (standaardnaam) ((?<One>abc)\d+)?(?<Two>xyz)(.*)
1 1 (standaardnaam) ((?<One>abc)\d+)
2 2 (standaardnaam) (.*)
3 Eén (?<One>abc)
4 Twee (?<Two>xyz)

In het volgende voorbeeld ziet u een reguliere expressie die dubbele woorden identificeert en het woord dat direct volgt op elk gedupliceerd woord. Het reguliere expressiepatroon definieert twee benoemde subexpressies: duplicateWord, dat het gedupliceerde woord vertegenwoordigt en nextWordhet woord dat volgt op het gedupliceerde woord.

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'.

Het reguliere expressiepatroon is als volgt:

(?<duplicateWord>\w+)\s\k<duplicateWord>\W(?<nextWord>\w+)

In de volgende tabel ziet u hoe de reguliere expressie wordt geïnterpreteerd.

Patroon Beschrijving
(?<duplicateWord>\w+) Komt overeen met een of meer woordtekens. Geef deze opnamegroep duplicateWordeen naam.
\s Overeenkomst met een spatieteken.
\k<duplicateWord> Komt overeen met de tekenreeks uit de vastgelegde groep met de naam duplicateWord.
\W Komt overeen met een niet-woordteken, inclusief spatie en leestekens. Dit voorkomt dat het reguliere expressiepatroon overeenkomt met een woord dat begint met het woord uit de eerste vastgelegde groep.
(?<nextWord>\w+) Komt overeen met een of meer woordtekens. Geef deze opnamegroep nextWordeen naam.

Een groepsnaam kan in een reguliere expressie worden herhaald. Het is bijvoorbeeld mogelijk dat meer dan één groep een naam digitkrijgt, zoals in het volgende voorbeeld wordt geïllustreerd. In het geval van dubbele namen wordt de waarde van het Group object bepaald door de laatste geslaagde opname in de invoertekenreeks. Bovendien wordt het CaptureCollection gevuld met informatie over elke opname, net zoals het zou zijn als de groepsnaam niet werd gedupliceerd.

In het volgende voorbeeld bevat de reguliere expressie \D+(?<digit>\d+)\D+(?<digit>\d+)? twee exemplaren van een groep met de naam digit. De eerste digit benoemde groep legt een of meer cijfers vast. De tweede benoemde digit groep legt nul of één exemplaar van een of meer cijfers vast. Zoals in de uitvoer van het voorbeeld wordt weergegeven, definieert de waarde van die tekst de waarde van het Group object als de tweede vastleggende groep met succes overeenkomt met de tekst. Als de tweede vastleggende groep niet overeenkomt met de invoertekenreeks, definieert de waarde van de laatste geslaagde overeenkomst de waarde van het Group object.

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

In de volgende tabel ziet u hoe de reguliere expressie wordt geïnterpreteerd.

Patroon Beschrijving
\D+ Komt overeen met een of meer niet-decimale tekens.
(?<digit>\d+) Kom overeen met een of meer decimale cijfers. Wijs de overeenkomst toe aan de digit benoemde groep.
\D+ Komt overeen met een of meer niet-decimale tekens.
(?<digit>\d+)? Kom overeen met nul of één exemplaar van een of meer decimale cijfers. Wijs de overeenkomst toe aan de digit benoemde groep.

Groepsdefinities verdelen

Een taakverdelingsgroepdefinitie verwijdert de definitie van een eerder gedefinieerde groep en slaat, in de huidige groep, het interval tussen de eerder gedefinieerde groep en de huidige groep op. Deze groeperingsconstructie heeft de volgende indeling:

(?<name1-name2>subexpression)

of:

(?'name1-name2' subexpression)

Hier is name1 de huidige groep (optioneel), naam2 is een eerder gedefinieerde groep en subexpressie is een geldig reguliere expressiepatroon. Met de definitie van de taakverdelingsgroep wordt de definitie van naam2 verwijderd en wordt het interval tussen naam2 en naam1 opgeslagen in naam1. Als er geen naam2-groep is gedefinieerd, wordt de overeenkomende backtracks gedefinieerd. Omdat bij het verwijderen van de laatste definitie van naam2 de vorige definitie van naam2 wordt weergegeven, kunt u met deze constructie de stapel opnamen voor groepsnaam2 gebruiken als teller voor het bijhouden van geneste constructies, zoals haakjes of haakjes openen en sluiten.

De definitie van de taakverdelingsgroep maakt gebruik van name2 als een stack. Het beginteken van elke geneste constructie wordt in de groep geplaatst en in de Group.Captures verzameling. Wanneer het afsluitende teken overeenkomt, wordt het bijbehorende openingsteken uit de groep verwijderd en wordt de Captures verzameling met één afgenomen. Nadat de tekens voor openen en sluiten van alle geneste constructies overeenkomen, is naam2 leeg.

Notitie

Nadat u de reguliere expressie in het volgende voorbeeld hebt gewijzigd om het juiste openings- en afsluitteken van een geneste constructie te gebruiken, kunt u deze gebruiken om de meeste geneste constructies te verwerken, zoals wiskundige expressies of programmacoderegels die meerdere geneste methodeaanroepen bevatten.

In het volgende voorbeeld wordt een definitie van een taakgroep gebruikt die overeenkomt met vierkante haakjes links en rechts (<>) in een invoertekenreeks. In het voorbeeld worden twee benoemde groepen Open gedefinieerd en Close, die worden gebruikt als een stapel om overeenkomende paren haakjes te volgen. Elke vastgelegde vierkante haak links wordt naar de opnameverzameling van de Open groep gepusht en elke vastgelegde rechte hoekhaak wordt naar de opnameverzameling van de Close groep gepusht. De definitie van de taakverdelingsgroep zorgt ervoor dat er een overeenkomende rechte hoekhaak is voor elke vierkante haak links. Als dat niet het probleem is, wordt de laatste submap (?(Open)(?!))alleen geëvalueerd als de Open groep niet leeg is (en dus, als alle geneste constructies niet zijn gesloten). Als het laatste subpatroon wordt geëvalueerd, mislukt de overeenkomst, omdat de (?!) subpatroon een negatieve lookahead-assertie met nulbreedte is die altijd mislukt.

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>

Het reguliere expressiepatroon is:

^[^<>]*(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)*(?(Open)(?!))$

De reguliere expressie wordt als volgt geïnterpreteerd:

Patroon Beschrijving
^ Begin aan het begin van de tekenreeks.
[^<>]* Kom overeen met nul of meer tekens die geen vierkante haakjes links of rechts zijn.
(?'Open'<) Koppel een vierkante haak aan de linkerkant en wijs deze toe aan een groep met de naam Open.
[^<>]* Kom overeen met nul of meer tekens die geen vierkante haakjes links of rechts zijn.
((?'Open'<)[^<>]*)+ Komt overeen met een of meer exemplaren van een haakje links, gevolgd door nul of meer tekens die geen vierkante haakjes links of rechts zijn. Dit is de tweede vastleggende groep.
(?'Close-Open'>) Koppel een rechte hoekhaak, wijs de subtekenreeks tussen de Open groep en de huidige groep toe aan de Close groep en verwijder de definitie van de Open groep.
[^<>]* Kom overeen met nul of meer exemplaren van een teken dat geen haakje links of rechts is.
((?'Close-Open'>)[^<>]*)+ Komt overeen met een of meer exemplaren van een vierkante haak rechts, gevolgd door nul of meer exemplaren van een teken dat geen linker- of rechterhoekhaak is. Wanneer u de rechte hoekhaak koppelt, wijst u de subtekenreeks tussen de Open groep en de huidige groep toe aan de Close groep en verwijdert u de definitie van de Open groep. Dit is de derde groep die vastlegt.
(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)* Kom overeen met nul of meer exemplaren van het volgende patroon: een of meer exemplaren van een haakje links, gevolgd door nul of meer niet-hoekhaaktekens, gevolgd door een of meer exemplaren van een rechte hoekhaak, gevolgd door nul of meer exemplaren van haakjes zonder hoek. Wanneer u de rechte hoekhaak koppelt, verwijdert u de definitie van de Open groep en wijst u de subtekenreeks tussen de Open groep en de huidige groep toe aan de Close groep. Dit is de eerste opnamegroep.
(?(Open)(?!)) Als de Open groep bestaat, moet u de overeenkomst afbreken als een lege tekenreeks kan worden vergeleken, maar niet de positie van de engine voor reguliere expressies in de tekenreeks vooruitgaan. Dit is een negatieve lookahead-assertie met nul breedte. Omdat een lege tekenreeks altijd impliciet aanwezig is in een invoertekenreeks, mislukt deze overeenkomst altijd. Het mislukken van deze overeenkomst geeft aan dat de punthaken niet in balans zijn.
$ Komt overeen met het einde van de invoertekenreeks.

De laatste subexpressie, (?(Open)(?!))geeft aan of de geneste constructies in de invoertekenreeks correct zijn verdeeld (bijvoorbeeld of elke haak linkse hoek overeenkomt met een rechte hoekhaak). Er wordt gebruikgemaakt van voorwaardelijke overeenkomsten op basis van een geldige vastgelegde groep; Zie Alternation Constructs voor meer informatie. Als de Open groep is gedefinieerd, probeert de engine voor reguliere expressies de subexpressie (?!) in de invoertekenreeks te vinden. De Open groep moet alleen worden gedefinieerd als geneste constructies niet in evenwicht zijn. Daarom moet het patroon dat moet worden vergeleken in de invoertekenreeks een patroon zijn dat ervoor zorgt dat de overeenkomst altijd mislukt. In dit geval (?!) is een negatieve lookahead-assertie met nulbreedte die altijd mislukt, omdat een lege tekenreeks altijd impliciet aanwezig is op de volgende positie in de invoertekenreeks.

In het voorbeeld evalueert de engine voor reguliere expressies de invoertekenreeks '<abc><mno<xyz>>', zoals wordt weergegeven in de volgende tabel.

Stap Patroon Resultaat
1 ^ Hiermee start u de overeenkomst aan het begin van de invoertekenreeks
2 [^<>]* Hiermee wordt gezocht naar niet-hoekhaaktekens vóór de haak links; zoekt geen overeenkomsten.
3 (((?'Open'<) Komt overeen met de haak links in abc<> en wijst deze toe aan de Open groep.
4 [^<>]* Komt overeen met abc.
5 )+ '<abc' is de waarde van de tweede vastgelegde groep.

Het volgende teken in de invoertekenreeks is geen haakje links, dus de engine voor reguliere expressies loopt niet terug naar het (?'Open'<)[^<>]*) subpatroon.
6 ((?'Close-Open'>) Komt overeen met de rechte hoekhaak in '<abc>', wijst 'abc' toe. Dit is de subtekenreeks tussen de Open groep en de rechterhoekhaak, aan de Close groep en verwijdert de huidige waarde ("<") van de groep, waardoor deze Open leeg blijft.
7 [^<>]* Hiermee wordt gezocht naar niet-hoekhaaktekens na de rechte hoekhaak; zoekt geen overeenkomsten.
8 )+ De waarde van de derde vastgelegde groep is '>'.

Het volgende teken in de invoertekenreeks is geen rechte hoekhaak, dus de engine voor reguliere expressies wordt niet teruggezet naar het ((?'Close-Open'>)[^<>]*) subpatroon.
9 )* De waarde van de eerste vastgelegde groep is '<abc>'.

Het volgende teken in de invoertekenreeks is een haakje links, zodat de engine voor reguliere expressies terugloopt naar het (((?'Open'<) subpatroon.
10 (((?'Open'<) Komt overeen met de vierkante haak links in '<mno' en wijst deze toe aan de Open groep. De Group.Captures verzameling heeft nu één waarde, "<".
11 [^<>]* Komt overeen met 'mno'.
12 )+ '<mno' is de waarde van de tweede vastgelegde groep.

Het volgende teken in de invoertekenreeks is een haakje links, zodat de engine voor reguliere expressies terugloopt naar het (?'Open'<)[^<>]*) subpatroon.
13 (((?'Open'<) Komt overeen met de vierkante haak links in '<xyz>' en wijst deze toe aan de Open groep. De Group.Captures verzameling van de Open groep bevat nu twee opnamen: de haak links van de hoek van '<mno' en de linkerhoekhaak van '<xyz>'.
14 [^<>]* Komt overeen met 'xyz'.
15 )+ '<xyz' is de waarde van de tweede vastgelegde groep.

Het volgende teken in de invoertekenreeks is geen haakje links, dus de engine voor reguliere expressies loopt niet terug naar het (?'Open'<)[^<>]*) subpatroon.
16 ((?'Close-Open'>) Komt overeen met de rechte hoekhaak in '<xyz>'. 'xyz', wijst de subtekenreeks tussen de Open groep en de rechte hoekhaak toe aan de Close groep en verwijdert de huidige waarde van de Open groep. De waarde van de vorige opname (de vierkante haak links in '<mno') wordt de huidige waarde van de Open groep. De Captures verzameling van de Open groep bevat nu één opname, de vierkante haak links van '<xyz>'.
17 [^<>]* Hiermee wordt gezocht naar haakjes zonder hoek; zoekt geen overeenkomsten.
18 )+ De waarde van de derde vastgelegde groep is '>'.

Het volgende teken in de invoertekenreeks is een haakje rechts, zodat de engine voor reguliere expressies terugloopt naar het ((?'Close-Open'>)[^<>]*) subpatroon.
19 ((?'Close-Open'>) Komt overeen met de laatste rechte hoekhaak in 'xyz>>', wijst 'mno<xyz>' (de subtekenreeks tussen de Open groep en de rechterhoekhaak) toe aan de Close groep en verwijdert de huidige waarde van de Open groep. De Open groep is nu leeg.
20 [^<>]* Hiermee wordt gezocht naar haakjes zonder hoek; zoekt geen overeenkomsten.
21 )+ De waarde van de derde vastgelegde groep is '>'.

Het volgende teken in de invoertekenreeks is geen rechte hoekhaak, dus de engine voor reguliere expressies wordt niet teruggezet naar het ((?'Close-Open'>)[^<>]*) subpatroon.
22 )* De waarde van de eerste vastgelegde groep is '<mno<xyz>>'.

Het volgende teken in de invoertekenreeks is geen haakje links, dus de engine voor reguliere expressies loopt niet terug naar het (((?'Open'<) subpatroon.
23 (?(Open)(?!)) De Open groep is niet gedefinieerd, dus er wordt geen overeenkomst geprobeerd.
24 $ Komt overeen met het einde van de invoertekenreeks.

Niet-aaneengesloten groepen

De volgende groeperingsconstructie legt niet de subtekenreeks vast die overeenkomt met een subexpressie:

(?:subexpression)

Hier is subexpressie een geldig patroon voor reguliere expressies. De niet-samenvattende groepsconstructie wordt meestal gebruikt wanneer een kwantificator wordt toegepast op een groep, maar de subtekenreeksen die door de groep zijn vastgelegd, zijn niet van belang.

Notitie

Als een reguliere expressie geneste groeperingsconstructies bevat, is een buitenste niet-inkapselende groepsconstructie niet van toepassing op de binnenste geneste groepsconstructies.

In het volgende voorbeeld ziet u een reguliere expressie met niet-inkapserende groepen. Houd er rekening mee dat de uitvoer geen vastgelegde groepen bevat.

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.

De reguliere expressie (?:\b(?:\w+)\W*)+\. komt overeen met een zin die wordt beëindigd door een punt. Omdat de reguliere expressie zich richt op zinnen en niet op afzonderlijke woorden, worden groeperingsconstructies uitsluitend gebruikt als kwantificatoren. Het patroon voor reguliere expressies wordt geïnterpreteerd zoals wordt weergegeven in de volgende tabel.

Patroon Beschrijving
\b Begin de overeenkomst bij een woordgrens.
(?:\w+) Komt overeen met een of meer woordtekens. Wijs de overeenkomende tekst niet toe aan een vastgelegde groep.
\W* Kom overeen met nul of meer niet-woordtekens.
(?:\b(?:\w+)\W*)+ Komt overeen met het patroon van een of meer woordtekens die beginnen bij een woordgrens, gevolgd door nul of meer niet-woordtekens, een of meer keren. Wijs de overeenkomende tekst niet toe aan een vastgelegde groep.
\. Overeenkomst met een punt.

Groepsopties

Met de volgende groeperingsconstructie worden de opgegeven opties binnen een subexpressie toegepast of uitgeschakeld:

(?imnsx-imnsx:subexpressie )

Hier is subexpressie een geldig patroon voor reguliere expressies. Hiermee schakelt u bijvoorbeeld (?i-s:) hoofdlettergevoeligheid in en schakelt u de modus met één regel uit. Zie Opties voor reguliere expressies voor meer informatie over de inlineopties die u kunt opgeven.

Notitie

U kunt opties opgeven die van toepassing zijn op een volledige reguliere expressie in plaats van een subexpressie met behulp van een System.Text.RegularExpressions.Regex klasseconstructor of een statische methode. U kunt ook inlineopties opgeven die van toepassing zijn na een specifiek punt in een reguliere expressie met behulp van de (?imnsx-imnsx) taalconstructie.

De groepsoptiesconstructie is geen groep die wordt vastgelegd. Dat wil gezegd, hoewel een deel van een tekenreeks die wordt vastgelegd door subexpressie in de overeenkomst is opgenomen, niet is opgenomen in een vastgelegde groep of wordt gebruikt om het GroupCollection object te vullen.

De reguliere expressie \b(?ix: d \w+)\s in het volgende voorbeeld maakt bijvoorbeeld gebruik van inlineopties in een groeperingsconstructie om hoofdlettergevoelige overeenkomsten mogelijk te maken en patroonspaties te negeren bij het identificeren van alle woorden die beginnen met de letter 'd'. De reguliere expressie wordt gedefinieerd zoals wordt weergegeven in de volgende tabel.

Patroon Beschrijving
\b Begin de overeenkomst bij een woordgrens.
(?ix: d \w+) Met hoofdlettergevoelige overeenkomsten en het negeren van witruimte in dit patroon, komt u overeen met een 'd' gevolgd door een of meer woordtekens.
\s Overeenkomst met een spatieteken.
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.      

Positieve lookahead-asserties met nulbreedte

In de volgende groeperingsconstructie wordt een positieve lookahead-assertie met nulbreedte gedefinieerd:

(?=subexpressie )

Hier is subexpressie een normaal expressiepatroon. Voor een geslaagde overeenkomst moet de invoertekenreeks overeenkomen met het reguliere expressiepatroon in subexpressie, hoewel de overeenkomende subtekenreeks niet is opgenomen in het resultaat van de overeenkomst. Een positieve lookahead-assertie van nulbreedte houdt geen backtrack.

Normaal gesproken vindt u een positieve lookahead-assertie met een nulbreedte aan het einde van een normaal expressiepatroon. Er wordt een subtekenreeks gedefinieerd die moet worden gevonden aan het einde van een tekenreeks voor een overeenkomst, maar die niet moet worden opgenomen in de overeenkomst. Het is ook handig om overmatige backtracking te voorkomen. U kunt een positieve lookahead-assertie met nulbreedte gebruiken om ervoor te zorgen dat een bepaalde vastgelegde groep begint met tekst die overeenkomt met een subset van het patroon dat is gedefinieerd voor die vastgelegde groep. Als een vastleggende groep bijvoorbeeld overeenkomt met opeenvolgende woordtekens, kunt u een positieve lookahead-assertie met nulbreedte gebruiken om te vereisen dat het eerste teken een alfabetisch hoofdletterteken is.

In het volgende voorbeeld wordt een positieve lookahead-assertie met nulbreedte gebruikt die overeenkomt met het woord 'is' in de invoertekenreeks.

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'.

De reguliere expressie \b\w+(?=\sis\b) wordt geïnterpreteerd zoals weergegeven in de volgende tabel.

Patroon Beschrijving
\b Begin de overeenkomst bij een woordgrens.
\w+ Komt overeen met een of meer woordtekens.
(?=\sis\b) Bepaal of de woordtekens worden gevolgd door een spatie en de tekenreeks 'is', die eindigt op een woordgrens. Zo ja, dan is de overeenkomst geslaagd.

Negatieve lookahead-asserties met nulbreedte

In de volgende groeperingsconstructie wordt een negatieve lookahead-assertie met nulbreedte gedefinieerd:

(?!subexpressie )

Hier is subexpressie een normaal expressiepatroon. Voor een geslaagde overeenkomst mag de invoertekenreeks niet overeenkomen met het reguliere expressiepatroon in subexpressie, hoewel de overeenkomende tekenreeks niet is opgenomen in het resultaat van de overeenkomst.

Een negatieve lookahead-assertie van nulbreedte wordt meestal gebruikt aan het begin of aan het einde van een reguliere expressie. Aan het begin van een reguliere expressie kan een specifiek patroon worden gedefinieerd dat niet moet worden vergeleken wanneer het begin van de reguliere expressie een vergelijkbaar, maar meer algemeen patroon definieert dat moet worden vergeleken. In dit geval wordt het vaak gebruikt om backtracking te beperken. Aan het einde van een reguliere expressie kan een subexpressie worden gedefinieerd die niet kan optreden aan het einde van een overeenkomst.

In het volgende voorbeeld wordt een reguliere expressie gedefinieerd die gebruikmaakt van een lookahead-assertie met nul breedte aan het begin van de reguliere expressie, zodat deze overeenkomt met woorden die niet beginnen met '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

De reguliere expressie \b(?!un)\w+\b wordt geïnterpreteerd zoals weergegeven in de volgende tabel.

Patroon Beschrijving
\b Begin de overeenkomst bij een woordgrens.
(?!un) Bepaal of de volgende twee tekens 'un' zijn. Als dat niet zo is, is een overeenkomst mogelijk.
\w+ Komt overeen met een of meer woordtekens.
\b Beëindig de overeenkomst op een woordgrens.

In het volgende voorbeeld wordt een reguliere expressie gedefinieerd die een lookahead-assertie met nul breedte aan het einde van de reguliere expressie gebruikt om woorden te vinden die niet eindigen met een interpunctieteken.

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

De reguliere expressie \b\w+\b(?!\p{P}) wordt geïnterpreteerd zoals weergegeven in de volgende tabel.

Patroon Beschrijving
\b Begin de overeenkomst bij een woordgrens.
\w+ Komt overeen met een of meer woordtekens.
\b Beëindig de overeenkomst op een woordgrens.
\p{P}) Als het volgende teken geen interpunctiesymbool (zoals een punt of komma) is, slaagt de overeenkomst.

Positieve lookbehind-asserties met nulbreedte

In de volgende groeperingsconstructie wordt een positieve lookbehind-assertie met nulbreedte gedefinieerd:

(?<=subexpressie )

Hier is subexpressie een normaal expressiepatroon. Voor een geslaagde overeenkomst moet subexpressie plaatsvinden in de invoertekenreeks links van de huidige positie, hoewel subexpression deze niet is opgenomen in het resultaat van de overeenkomst. Een positieve lookbehind-assertie met nulbreedte loopt niet terug.

Positieve lookbehind-asserties van nulbreedte worden meestal gebruikt aan het begin van reguliere expressies. Het patroon dat ze definiëren, is een voorwaarde voor een overeenkomst, hoewel het geen deel uitmaakt van het resultaat van de overeenkomst.

Het volgende voorbeeld komt bijvoorbeeld overeen met de laatste twee cijfers van het jaar voor de 2e eerste eeuw (dat wil bijvoorbeeld dat de cijfers '20' voorafgaan aan de overeenkomende tekenreeks).

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

Het patroon voor reguliere expressies (?<=\b20)\d{2}\b wordt geïnterpreteerd zoals wordt weergegeven in de volgende tabel.

Patroon Beschrijving
\d{2} Kom overeen met twee decimalen.
(?<=\b20) Ga door met de overeenkomst als de twee decimale cijfers worden voorafgegaan door de decimale cijfers '20' op een woordgrens.
\b Beëindig de overeenkomst op een woordgrens.

Positieve lookbehind-asserties met nulbreedte worden ook gebruikt om de backtracking te beperken wanneer het laatste teken of de laatste tekens in een vastgelegde groep een subset moeten zijn van de tekens die overeenkomen met het normale expressiepatroon van die groep. Als een groep bijvoorbeeld alle opeenvolgende woordtekens vastlegt, kunt u een positieve lookbehind-assertie met nulbreedte gebruiken om te vereisen dat het laatste teken alfabetisch is.

Negatieve lookbehind-asserties met nulbreedte

De volgende groeperingsconstructie definieert een negatieve lookbehind-assertie met nul breedte:

(?<!subexpressie )

Hier is subexpressie een normaal expressiepatroon. Voor een geslaagde overeenkomst mag subexpressie niet plaatsvinden in de invoertekenreeks links van de huidige positie. Subtekenreeksen die niet overeenkomen subexpression , worden echter niet opgenomen in het resultaat van de overeenkomst.

Negatieve lookbehind-asserties met nulbreedte worden meestal gebruikt aan het begin van reguliere expressies. Het patroon dat ze definiëren, sluit een overeenkomst in de tekenreeks die volgt uit. Ze worden ook gebruikt om de backtracking te beperken wanneer het laatste teken of de laatste tekens in een vastgelegde groep niet een of meer tekens mogen zijn die overeenkomen met het normale expressiepatroon van die groep. Als een groep bijvoorbeeld alle opeenvolgende woordtekens vastlegt, kunt u een positieve lookbehind-assertie met nulbreedte gebruiken om te vereisen dat het laatste teken geen onderstrepingsteken (_) is.

Het volgende voorbeeld komt overeen met de datum voor een dag van de week die geen weekend is (dat wil dus niet zaterdag of zondag zijn).

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

Het patroon voor reguliere expressies (?<!(Saturday|Sunday) )\b\w+ \d{1,2}, \d{4}\b wordt geïnterpreteerd zoals wordt weergegeven in de volgende tabel.

Patroon Beschrijving
\b Begin de overeenkomst bij een woordgrens.
\w+ Komt overeen met een of meer woordtekens, gevolgd door een spatieteken.
\d{1,2}, Kom overeen met een of twee decimale cijfers, gevolgd door een spatie en een komma.
\d{4}\b Kom overeen met vier decimalen en beëindig de overeenkomst op een woordgrens.
(?<!(Saturday|Sunday) ) Als de overeenkomst wordt voorafgegaan door iets anders dan de tekenreeksen 'zaterdag' of 'zondag' gevolgd door een spatie, is de overeenkomst geslaagd.

Atomische groepen

De volgende groeperingsconstructie vertegenwoordigt een atomische groep (bekend in een aantal andere reguliere expressie-engines als een subexpressie die niet wordt teruggeleid, een atomische subexpressie of een eenmalige subexpressie):

(?>subexpressie )

Hier is subexpressie een normaal expressiepatroon.

Normaal gesproken kan de reguliere expressie, als een reguliere expressie een optioneel of alternatief overeenkomend patroon bevat en een overeenkomst niet slaagt, de engine voor reguliere expressies in meerdere richtingen vertakken om een invoertekenreeks met een patroon te vinden. Als een overeenkomst niet wordt gevonden wanneer de eerste vertakking wordt gebruikt, kan de engine voor reguliere expressies een back-up maken of teruggaan naar het punt waar de eerste overeenkomst is genomen en de overeenkomst proberen met behulp van de tweede vertakking. Dit proces kan worden voortgezet totdat alle vertakkingen zijn geprobeerd.

De (?>subexpressietaalconstructie) schakelt backtracking uit. De engine voor reguliere expressies komt overeen met zoveel tekens in de invoertekenreeks als mogelijk. Als er geen verdere overeenkomst mogelijk is, wordt er geen backtrack uitgevoerd om alternatieve patroonovereenkomsten te proberen. (Dat wil gezegd, de subexpressie komt alleen overeen met tekenreeksen die alleen door de subexpressie worden vergeleken. Er wordt niet geprobeerd een tekenreeks te vinden op basis van de subexpressie en eventuele subexpressies die hierop volgen.)

Deze optie wordt aanbevolen als u weet dat backtracking niet lukt. Voorkomen dat de engine voor reguliere expressies onnodig zoeken uitvoert, verbetert de prestaties.

In het volgende voorbeeld ziet u hoe een atomische groep de resultaten van een patroonovereenkomst wijzigt. De backtracking van de reguliere expressie komt overeen met een reeks herhaalde tekens, gevolgd door een meer exemplaar van hetzelfde teken op een woordgrens, maar de niet-backbacktracking reguliere expressie niet.

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

De reguliere expressie (?>(\w)\1+).\b voor niet-backtracking wordt gedefinieerd zoals wordt weergegeven in de volgende tabel.

Patroon Beschrijving
(\w) Koppel één woord aan één woord en wijs het toe aan de eerste groep voor vastleggen.
\1+ Komt overeen met de waarde van de eerste vastgelegde subtekenreeks een of meer keren.
. Match een willekeurig teken.
\b Beëindig de overeenkomst op een woordgrens.
(?>(\w)\1+) Komt overeen met een of meer exemplaren van een gedupliceerd woordteken, maar ga niet terug naar het laatste teken op een woordgrens.

Groeperingsconstructies en reguliere expressieobjecten

Subtekenreeksen die overeenkomen met een reguliere expressie die een groep vastlegt, worden weergegeven door System.Text.RegularExpressions.Group objecten die kunnen worden opgehaald uit het System.Text.RegularExpressions.GroupCollection object dat door de Match.Groups eigenschap wordt geretourneerd. Het GroupCollection object wordt als volgt ingevuld:

  • Het eerste Group object in de verzameling (het object op index nul) vertegenwoordigt de hele overeenkomst.
  • De volgende set Group objecten vertegenwoordigt niet-benoemde (genummerde) vastleggen van groepen. Ze worden weergegeven in de volgorde waarin ze zijn gedefinieerd in de reguliere expressie, van links naar rechts. De indexwaarden van deze groepen variëren van 1 tot het aantal niet-benoemde vastleggen van groepen in de verzameling. (De index van een bepaalde groep is gelijk aan de genummerde backreference. Zie Backreference Constructs voor meer informatie over backreferences.)
  • De laatste set Group objecten vertegenwoordigen benoemde groepen vastleggen. Ze worden weergegeven in de volgorde waarin ze zijn gedefinieerd in de reguliere expressie, van links naar rechts. De indexwaarde van de eerste benoemde groep die de groep vastlegt, is één groter dan de index van de laatst benoemde vastleggende groep. Als er geen niet-benoemde opnamegroepen in de reguliere expressie zijn, is de indexwaarde van de eerste benoemde groep vastleggen er een.

Als u een kwantificator toepast op een vastleggende groep, geven de bijbehorende Group objecten Capture.IndexCapture.ValueCapture.Length en eigenschappen de laatste subtekenreeks weer die wordt vastgelegd door een groep die wordt vastgelegd. U kunt een volledige set subtekenreeksen ophalen die worden vastgelegd door groepen die kwantificeerders hebben van het CaptureCollection object dat door de Group.Captures eigenschap wordt geretourneerd.

In het volgende voorbeeld wordt de relatie tussen de Group en Capture objecten verduidelijkt.

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'

Met het patroon reguliere expressie (\b(\w+)\W+)+ worden afzonderlijke woorden uit een tekenreeks geëxtraheerd. Deze wordt gedefinieerd zoals wordt weergegeven in de volgende tabel.

Patroon Beschrijving
\b Begin de overeenkomst bij een woordgrens.
(\w+) Komt overeen met een of meer woordtekens. Samen vormen deze tekens een woord. Dit is de tweede vastleggende groep.
\W+ Komt overeen met een of meer niet-woordtekens.
(\b(\w+)\W+) Komt overeen met het patroon van een of meer woordtekens gevolgd door een of meer niet-woordtekens een of meer keren. Dit is de eerste opnamegroep.

De tweede groep die een groep vastlegt, komt overeen met elk woord van de zin. De eerste opnamegroep komt overeen met elk woord, samen met de leestekens en witruimte die het woord volgen. Het Group object waarvan de index 2 is, bevat informatie over de tekst die overeenkomt met de tweede opnamegroep. De volledige set woorden die zijn vastgelegd door de groep vastleggen, zijn beschikbaar vanuit het CaptureCollection object dat door de Group.Captures eigenschap wordt geretourneerd.

Zie ook