Konstrukcje dopasowań w wyrażeniach regularnychBackreference Constructs in Regular Expressions

Dopasowywania wstecznego zapewniają wygodny sposób identyfikowania powtarzających się znaków lub podciągu wewnątrz ciągu.Backreferences provide a convenient way to identify a repeated character or substring within a string. Na przykład jeśli ciąg wejściowy zawiera wiele wystąpień dowolnego podciąg, można dopasować pierwsze wystąpienie z grupy przechwytywania, a następnie należy użyć dopasowywania wstecznego do dopasowania pozostałe wystąpienia podciągu.For example, if the input string contains multiple occurrences of an arbitrary substring, you can match the first occurrence with a capturing group, and then use a backreference to match subsequent occurrences of the substring.

Uwaga

Oddzielne składnia jest używana do odwoływania się do nazwanych i numerowanej grupy w ciągach zastąpienie przechwytywania.A separate syntax is used to refer to named and numbered capturing groups in replacement strings. Aby uzyskać więcej informacji, zobacz podstawienia.For more information, see Substitutions.

.NET definiuje elementy języka oddzielnych do odwoływania się do numerowane i nazwanych grup przechwytywania..NET defines separate language elements to refer to numbered and named capturing groups. Aby uzyskać więcej informacji na temat grupy przechwytywania, zobacz Grouping Constructs.For more information about capturing groups, see Grouping Constructs.

Numerowany dopasowywania wstecznegoNumbered Backreferences

Numerowany dopasowywania wstecznego używa następującej składni:A numbered backreference uses the following syntax:

\ Numer\ number

gdzie numer jest numerem porządkowym grupy przechwytywania w wyrażeniu regularnym.where number is the ordinal position of the capturing group in the regular expression. Na przykład \4 pasuje do zawartości czwarty grupa przechwytywania.For example, \4 matches the contents of the fourth capturing group. Jeśli numer jest niezdefiniowana we wzorcu wyrażenia regularnego, występuje błąd analizy, i zgłasza aparat wyrażeń regularnych ArgumentException.If number is not defined in the regular expression pattern, a parsing error occurs, and the regular expression engine throws an ArgumentException. Na przykład, wyrażenie regularne \b(\w+)\s\1 jest prawidłowy, ponieważ (\w+) jest pierwszą i jedyną grupa przechwytywania w wyrażeniu.For example, the regular expression \b(\w+)\s\1 is valid, because (\w+) is the first and only capturing group in the expression. Z drugiej strony \b(\w+)\s\2 jest nieprawidłowy i zgłasza wyjątek argumentu, ponieważ nie istnieje żadna grupa przechwytywania numerowane \2.On the other hand, \b(\w+)\s\2 is invalid and throws an argument exception, because there is no capturing group numbered \2. Ponadto jeśli numer identyfikuje grupy przechwytywania w określonym położeniu porządkowe, ale ta grupa przechwytywania przypisano liczbową nazwa różni się od jego porządkowym, analizator składni wyrażeń regularnych generuje również ArgumentException.In addition, if number identifies a capturing group in a particular ordinal position, but that capturing group has been assigned a numeric name different than its ordinal position, the regular expression parser also throws an ArgumentException.

Należy pamiętać, niejednoznaczności między kody unikowe ósemkowe (takie jak \16) i \ numer dopasowywania wstecznego, użyj takiej samej notacji.Note the ambiguity between octal escape codes (such as \16) and \number backreferences that use the same notation. Tę niejednoznaczność zostanie rozwiązany w następujący sposób:This ambiguity is resolved as follows:

  • Wyrażenia \1 za pośrednictwem \9 są zawsze interpretowane jako odwołania wsteczne, a nie jako ósemkowe kodów.The expressions \1 through \9 are always interpreted as backreferences, and not as octal codes.

  • Jeżeli pierwsza cyfra multidigit wyrażenie jest 8 i 9 (takie jak \80 lub \91), wyrażeń, jak interpretować jako literał.If the first digit of a multidigit expression is 8 or 9 (such as \80 or \91), the expression as interpreted as a literal.

  • Wyrażenia z \10 i większa jest uznawana za odwołaniem wstecznym, jeśli istnieje odwołanie wsteczne odpowiadającej pozycji oznacza numer; w przeciwnym razie, są interpretowane jako ósemkowe kodów.Expressions from \10 and greater are considered backreferences if there is a backreference corresponding to that number; otherwise, they are interpreted as octal codes.

  • Jeśli wyrażenie regularne zawiera odwołanie wsteczne numer nedefinovanou, wystąpi błąd podczas analizowania, i zgłasza aparat wyrażeń regularnych ArgumentException.If a regular expression contains a backreference to an undefined group number, a parsing error occurs, and the regular expression engine throws an ArgumentException.

W przypadku niejednoznaczności problemu, można użyć \k< nazwa > notacji, która jest jednoznaczny i nie należy mylić z kody znaków ósemkowych.If the ambiguity is a problem, you can use the \k<name> notation, which is unambiguous and cannot be confused with octal character codes. Podobnie, szesnastkowe kody takich jak \xdd jednoznaczne i nie należy mylić z odwołań wstecznych.Similarly, hexadecimal codes such as \xdd are unambiguous and cannot be confused with backreferences.

Poniższy przykład umożliwia znalezienie word podwojone znaki w ciągu.The following example finds doubled word characters in a string. Definiuje wyrażenie regularne (\w)\1, który składa się z następujących elementów.It defines a regular expression, (\w)\1, which consists of the following elements.

ElementElement OpisDescription
(\w) Dopasuj znak wyrazu i przypisać je do pierwszej grupy przechwytywania.Match a word character and assign it to the first capturing group.
\1 Dopasowuje znak dalej, która jest taka sama jak wartość pierwszą grupę przechwytywania.Match the next character that is the same as the value of the first capturing group.
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"(\w)\1";
      string input = "trellis llama webbing dresser swagger";
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("Found '{0}' at position {1}.", 
                           match.Value, match.Index);
   }
}
// The example displays the following output:
//       Found 'll' at position 3.
//       Found 'll' at position 8.
//       Found 'bb' at position 16.
//       Found 'ss' at position 25.
//       Found 'gg' at position 33.
Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern As String = "(\w)\1"
      Dim input As String = "trellis llama webbing dresser swagger"
      For Each match As Match In Regex.Matches(input, pattern)
         Console.WriteLine("Found '{0}' at position {1}.", _
                           match.Value, match.Index)
      Next   
   End Sub
End Module
' The example displays the following output:
'       Found 'll' at position 3.
'       Found 'll' at position 8.
'       Found 'bb' at position 16.
'       Found 'ss' at position 25.
'       Found 'gg' at position 33.

Nazwane dopasowywania wstecznegoNamed Backreferences

Nazwane dopasowanie wsteczne to zdefiniowane przy użyciu następującej składni:A named backreference is defined by using the following syntax:

\k< Nazwa >\k< name >

lub:or:

\k' Nazwa '\k' name '

gdzie nazwa to nazwa grupy przechwytywania zdefiniowanej we wzorcu wyrażenia regularnego.where name is the name of a capturing group defined in the regular expression pattern. Jeśli nazwa jest niezdefiniowana we wzorcu wyrażenia regularnego, występuje błąd analizy, i zgłasza aparat wyrażeń regularnych ArgumentException.If name is not defined in the regular expression pattern, a parsing error occurs, and the regular expression engine throws an ArgumentException.

Poniższy przykład umożliwia znalezienie word podwojone znaki w ciągu.The following example finds doubled word characters in a string. Definiuje wyrażenie regularne (?<char>\w)\k<char>, który składa się z następujących elementów.It defines a regular expression, (?<char>\w)\k<char>, which consists of the following elements.

ElementElement OpisDescription
(?<char>\w) Dopasuj znak wyrazu i przypisz je do grupy przechwytywania o nazwie char.Match a word character and assign it to a capturing group named char.
\k<char> Następny znak, który jest taka sama jak wartość dopasowania char grupa przechwytywania.Match the next character that is the same as the value of the char capturing group.
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"(?<char>\w)\k<char>";
      string input = "trellis llama webbing dresser swagger";
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("Found '{0}' at position {1}.", 
                           match.Value, match.Index);
   }
}
// The example displays the following output:
//       Found 'll' at position 3.
//       Found 'll' at position 8.
//       Found 'bb' at position 16.
//       Found 'ss' at position 25.
//       Found 'gg' at position 33.
Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern As String = "(?<char>\w)\k<char>"
      Dim input As String = "trellis llama webbing dresser swagger"
      For Each match As Match In Regex.Matches(input, pattern)
         Console.WriteLine("Found '{0}' at position {1}.", _
                           match.Value, match.Index)
      Next   
   End Sub
End Module
' The example displays the following output:
'       Found 'll' at position 3.
'       Found 'll' at position 8.
'       Found 'bb' at position 16.
'       Found 'ss' at position 25.
'       Found 'gg' at position 33.

O nazwie liczbowych dopasowywania wstecznegoNamed numeric backreferences

W nazwane dopasowanie wsteczne z \k, nazwa może być również ciąg reprezentujący liczbę.In a named backreference with \k, name can also be the string representation of a number. Na przykład w poniższym przykładzie użyto wyrażenia regularnego (?<2>\w)\k<2> można znaleźć słowo podwojone znaki w ciągu.For example, the following example uses the regular expression (?<2>\w)\k<2> to find doubled word characters in a string. W takim przypadku w przykładzie zdefiniowano grupę przechwytywania, jawnie o nazwie "2", a odwołanie wsteczne odpowiednio o nazwie "2".In this case, the example defines a capturing group that is explicitly named "2", and the backreference is correspondingly named "2".

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"(?<2>\w)\k<2>";
      string input = "trellis llama webbing dresser swagger";
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("Found '{0}' at position {1}.", 
                           match.Value, match.Index);
   }
}
// The example displays the following output:
//       Found 'll' at position 3.
//       Found 'll' at position 8.
//       Found 'bb' at position 16.
//       Found 'ss' at position 25.
//       Found 'gg' at position 33.
Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern As String = "(?<2>\w)\k<2>"
      Dim input As String = "trellis llama webbing dresser swagger"
      For Each match As Match In Regex.Matches(input, pattern)
         Console.WriteLine("Found '{0}' at position {1}.", _
                           match.Value, match.Index)
      Next   
   End Sub
End Module
' The example displays the following output:
'       Found 'll' at position 3.
'       Found 'll' at position 8.
'       Found 'bb' at position 16.
'       Found 'ss' at position 25.
'       Found 'gg' at position 33.

Jeśli nazwa to ciąg reprezentujący liczbę, a nie grupy przechwytywania tej samej nazwie, \k< nazwa > jest taka sama jak odwołanie wsteczne \ Liczba, gdzie numer jest numerem porządkowym przechwytywania.If name is the string representation of a number, and no capturing group has that name, \k<name> is the same as the backreference \number, where number is the ordinal position of the capture. W poniższym przykładzie jest pojedynczy grupa przechwytywania o nazwie char.In the following example, there is a single capturing group named char. Konstrukcja dopasowywania wstecznego odwołuje się do niego jako \k<1>.The backreference construct refers to it as \k<1>. Jak wynika z w przykładzie pokazano wywołanie metody Regex.IsMatch powiedzie się, ponieważ char jest pierwszą grupę przechwytywania.As the output from the example shows, the call to the Regex.IsMatch succeeds because char is the first capturing group.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      Console.WriteLine(Regex.IsMatch("aa", @"(?<char>\w)\k<1>"));    
      // Displays "True".
   }
}


Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Console.WriteLine(Regex.IsMatch("aa", "(?<char>\w)\k<1>"))    
      ' Displays "True".
   End Sub
End Module

Jednak jeśli nazwa jest ciąg reprezentujący liczbę, a grupy przechwytywania w, że pozycja jawnie przypisano nazwy liczbowej, analizator składni wyrażeń regularnych nie może zidentyfikować grupa przechwytywania przez jego porządkowym .However, if name is the string representation of a number and the capturing group in that position has been explicitly assigned a numeric name, the regular expression parser cannot identify the capturing group by its ordinal position. Zamiast tego wyniku weryfikacji zgłasza wyjątek ArgumentException. Tylko grupy przechwytywania w poniższym przykładzie nosi nazwę "2".Instead, it throws an ArgumentException.The only capturing group in the following example is named "2". Ponieważ \k koncept jest wykorzystywany do definiowania odwołanie wsteczne o nazwie "1", analizator składni wyrażeń regularnych nie może zidentyfikować pierwszą grupę przechwytywania i zgłasza wyjątek.Because the \k construct is used to define a backreference named "1", the regular expression parser is unable to identify the first capturing group and throws an exception.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      Console.WriteLine(Regex.IsMatch("aa", @"(?<2>\w)\k<1>"));    
      // Throws an ArgumentException.
   }
}


Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Console.WriteLine(Regex.IsMatch("aa", "(?<2>\w)\k<1>"))    
      ' Throws an ArgumentException.
   End Sub
End Module

Jakie dopasowanie dopasowywania wstecznegoWhat Backreferences Match

Odwołanie wsteczne odnosi się do najnowszych definicji grupy (definicja najbardziej natychmiast po lewej stronie, podczas dopasowywania od lewej do prawej).A backreference refers to the most recent definition of a group (the definition most immediately to the left, when matching left to right). Gdy ułatwia grupy, który przechwytuje wielu, odwołanie wsteczne odnosi się do przechwytywania najbardziej aktualne.When a group makes multiple captures, a backreference refers to the most recent capture.

Poniższy przykład zawiera wzorzec wyrażenia regularnego (?<1>a)(?<1>\1b)*, które ponownie definiuje \1 o nazwie grupy.The following example includes a regular expression pattern, (?<1>a)(?<1>\1b)*, which redefines the \1 named group. W poniższej tabeli opisano każdy wzorzec w wyrażeniu regularnym.The following table describes each pattern in the regular expression.

WzorzecPattern OpisDescription
(?<1>a) Dopasowuje znak "a" i przypisz wynik do grupy przechwytywania o nazwie 1.Match the character "a" and assign the result to the capturing group named 1.
(?<1>\1b)* Dopasowuje zero lub więcej wystąpień grupy o nazwie 1 wraz z "b" i przypisz wynik do grupa przechwytywania o nazwie 1.Match zero or more occurrences of the group named 1 along with a "b", and assign the result to the capturing group named 1.
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"(?<1>a)(?<1>\1b)*";
      string input = "aababb";
      foreach (Match match in Regex.Matches(input, pattern))
      {
         Console.WriteLine("Match: " + match.Value);
         foreach (Group group in match.Groups)
            Console.WriteLine("   Group: " + group.Value);
      }
   }
}
// The example displays the following output:
//          Group: aababb
//          Group: abb
Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern As String = "(?<1>a)(?<1>\1b)*"
      Dim input As String = "aababb"
      For Each match As Match In Regex.Matches(input, pattern)
         Console.WriteLine("Match: " + match.Value)
         For Each group As Group In match.Groups
            Console.WriteLIne("   Group: " + group.Value)
         Next
      Next
   End Sub
End Module
' The example display the following output:
'          Group: aababb
'          Group: abb

Przy porównywaniu wyrażenia regularnego do ciągu wejściowego ("aababb"), aparat wyrażeń regularnych wykonuje następujące operacje:In comparing the regular expression with the input string ("aababb"), the regular expression engine performs the following operations:

  1. Rozpoczyna się od początku ciągu i dopasowuje pomyślnie "" z wyrażeniem (?<1>a).It starts at the beginning of the string, and successfully matches "a" with the expression (?<1>a). Wartość 1 grupy jest teraz "".The value of the 1 group is now "a".

  2. Przechodzi do drugim znakiem i pomyślnie pasuje do ciągu "ab" z wyrażeniem \1b, lub "ab".It advances to the second character, and successfully matches the string "ab" with the expression \1b, or "ab". Następnie przypisuje wynik, "ab", aby \1.It then assigns the result, "ab" to \1.

  3. Przechodzi do czwartej znaków.It advances to the fourth character. Wyrażenie (?<1>\1b)* to być dopasowane zero lub więcej razy, więc go pomyślnie pasuje do ciągu "abb" z wyrażeniem \1b.The expression (?<1>\1b)* is to be matched zero or more times, so it successfully matches the string "abb" with the expression \1b. Przypisuje wynik, "abb", wróć do \1.It assigns the result, "abb", back to \1.

W tym przykładzie * jest pętli kwantyfikator — zostanie ono ocenione wielokrotnie, dopóki aparat wyrażeń regularnych nie pasuje do wzorca, definiuje.In this example, * is a looping quantifier -- it is evaluated repeatedly until the regular expression engine cannot match the pattern it defines. Kwantyfikatory pętli nie usuwaj zaznaczenia opcji definicje grup.Looping quantifiers do not clear group definitions.

Jeśli grupa nie przechwytywane podciągi wszelkie odwołaniem wstecznym do tej grupy jest nieokreślone i nigdy nie jest zgodny.If a group has not captured any substrings, a backreference to that group is undefined and never matches. Jest to zilustrowane przez wzorzec wyrażenia regularnego \b(\p{Lu}{2})(\d{2})?(\p{Lu}{2})\b, która została zdefiniowana w następujący sposób:This is illustrated by the regular expression pattern \b(\p{Lu}{2})(\d{2})?(\p{Lu}{2})\b, which is defined as follows:

WzorzecPattern OpisDescription
\b Rozpoczyna dopasowanie na granicy wyrazu.Begin the match on a word boundary.
(\p{Lu}{2}) Dopasowuje dwie wielkie litery.Match two uppercase letters. Jest to pierwsza grupa przechwytywania.This is the first capturing group.
(\d{2})? Dopasowanie zera lub jednego wystąpienia dwóch cyfr dziesiętnych.Match zero or one occurrence of two decimal digits. Jest to druga grupa przechwytywania.This is the second capturing group.
(\p{Lu}{2}) Dopasowuje dwie wielkie litery.Match two uppercase letters. Jest to trzecia grupa przechwytywania.This is the third capturing group.
\b Zakończ dopasowanie na granicy wyrazu.End the match on a word boundary.

Ciąg wejściowy można dopasować tego wyrażenia regularnego, nawet jeśli nie są dwie cyfry dziesiętne, które są definiowane przez to druga grupa przechwytywania.An input string can match this regular expression even if the two decimal digits that are defined by the second capturing group are not present. Poniższy przykład pokazuje, czy mimo, że dopasowanie się powiedzie, pustej grupy przechwytywania znajduje się między dwiema grupami przechwytywania pomyślne.The following example shows that even though the match is successful, an empty capturing group is found between two successful capturing groups.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(\p{Lu}{2})(\d{2})?(\p{Lu}{2})\b";
      string[] inputs = { "AA22ZZ", "AABB" };
      foreach (string input in inputs)
      {
         Match match = Regex.Match(input, pattern);
         if (match.Success)
         {
            Console.WriteLine("Match in {0}: {1}", input, match.Value);
            if (match.Groups.Count > 1)
            {
               for (int ctr = 1; ctr <= match.Groups.Count - 1; ctr++)
               {
                  if (match.Groups[ctr].Success)
                     Console.WriteLine("Group {0}: {1}", 
                                       ctr, match.Groups[ctr].Value);
                  else
                     Console.WriteLine("Group {0}: <no match>", ctr);
               }
            }
         }
         Console.WriteLine();
      }      
   }
}
// The example displays the following output:
//       Match in AA22ZZ: AA22ZZ
//       Group 1: AA
//       Group 2: 22
//       Group 3: ZZ
//       
//       Match in AABB: AABB
//       Group 1: AA
//       Group 2: <no match>
//       Group 3: BB
Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern As String = "\b(\p{Lu}{2})(\d{2})?(\p{Lu}{2})\b"
      Dim inputs() As String = { "AA22ZZ", "AABB" }
      For Each input As String In inputs
         Dim match As Match = Regex.Match(input, pattern)
         If match.Success Then
            Console.WriteLine("Match in {0}: {1}", input, match.Value)
            If match.Groups.Count > 1 Then
               For ctr As Integer = 1 To match.Groups.Count - 1
                  If match.Groups(ctr).Success Then
                     Console.WriteLine("Group {0}: {1}", _
                                       ctr, match.Groups(ctr).Value)
                  Else
                     Console.WriteLine("Group {0}: <no match>", ctr)
                  End If      
               Next
            End If
         End If
         Console.WriteLine()
      Next      
   End Sub
End Module
' The example displays the following output:
'       Match in AA22ZZ: AA22ZZ
'       Group 1: AA
'       Group 2: 22
'       Group 3: ZZ
'       
'       Match in AABB: AABB
'       Group 1: AA
'       Group 2: <no match>
'       Group 3: BB

Zobacz takżeSee also