Share via


Constructions de backreference

Les références arrières offrent un moyen commode pour identifier un caractère répété ou une sous-chaîne dans une chaîne. Par exemple, si la chaîne d'entrée contient plusieurs occurrences d'une sous-chaîne arbitraire, vous pouvez mettre en correspondance la première occurrence avec un groupe de capture, puis utiliser une backreference pour faire correspondre les occurrences ultérieures de la sous-chaîne.

RemarqueRemarque

Une syntaxe séparée est utilisée pour faire référence aux groupes de capture nommés et numérotés dans les chaînes de remplacement.Pour plus d'informations, consultez Substitutions.

Le .NET Framework définit des éléments de langage différents pour qu'ils fassent référence aux groupes de capture comptés et nommés. Pour plus d'informations sur les groupes de capture, consultez Constructions de regroupement.

Backreferences numérotées

Une référence arrière numérotée utilise la syntaxe suivante :

\nombre

où number est la position ordinale du groupe de capture dans l'expression régulière. Par exemple, \4 correspond au contenu du quatrième groupe de capture. Si le nombre n'est pas défini dans le modèle d'expression régulière, une erreur d'analyse se produit, et le moteur des expressions régulières lève une exception ArgumentException. Par exemple, l'expression régulière \b(\w+)\s\1 est valide, parce que (\w+) est le premier et unique groupe de capture dans l'expression. En revanche, \b(\w+)\s\2 n'est pas valide et lève une exception d'argument, parce qu'il y a aucun groupe de capture numéroté \2.

Notez l'ambiguïté qui existe entre les codes d'échappement octaux (tels que \16) et les backreferences \nombre utilisant la même notation. Cette ambiguïté est résolue comme suit :

  • Les expressions \1 jusqu'à \9 sont toujours interprétées comme références arrières et non comme des codes octaux.

  • Si le premier chiffre d'une expression à plusieurs chiffres est 8 ou 9 (tel que \80 ou \91), l'expression est interprétée comme un littéral.

  • Les expressions de \10 et supérieur sont considérées comme des backreferences s'il y a un backreference qui correspond à ce nombre; sinon, elles sont interprétées comme codes octaux.

  • Si une expression régulière contient un backreference à un numéro de groupe indéfini, une erreur d'analyse se produit et le moteur des expressions régulières lève une exception ArgumentException.

Si l'ambiguïté est un problème, vous pouvez utiliser la \k<notation de nom>, qui est sans équivoque et qui ne peut pas être confondue avec les codes des caractères octaux. De la même façon, les codes hexadécimaux tels que \xdd ne sont pas ambigus et ne peuvent pas être confondus avec les backreferences.

L'exemple suivant trouve des caractères doubles dans une chaîne. Il définit une expression régulière, (\w)\1, qui se compose des éléments suivants.

Élément

Description

(\w)

Mettre en correspondance un caractère alphabétique et l'assigner au premier groupe de capture.

\1

Mettre en correspondance le caractère suivant qui est identique à la valeur du premier groupe de capture.

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

Backreferences nommées

Une référence arrière nommée est définie à l'aide de la syntaxe suivante :

\k<name>

ou :

\k'name'

où name est le nom d'un groupe de capture défini dans le modèle d'expression régulière. Si le nom n'est pas défini dans le modèle d'expression régulière, une erreur d'analyse se produit, et le moteur des expressions régulières lève une exception ArgumentException.

L'exemple suivant trouve des caractères doubles dans une chaîne. Il définit une expression régulière, (?<char>\w)\k<char>, qui se compose des éléments suivants.

Élément

Description

(?<char>\w)

Mettre en correspondance un caractère alphabétique et l'assigner à un groupe de capture nommé char.

\k<char>

Mettre en correspondance le caractère suivant qui est identique à la valeur du groupe de capture char.

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

Notez que le nom peut également être la représentation sous forme de chaîne d'un nombre. Par exemple, l'exemple suivant utilise l'expression régulière (?<2>\w)\k<2> pour rechercher des caractères alphabétiques doublés dans une chaîne.

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

Mise en correspondance de backreferences

Une backreference renvoie à la définition la plus récente d'un groupe (définition située à l'extrême gauche, lorsque la recherche s'effectue de gauche à droite). Lorsqu'un groupe effectue plusieurs captures, une backreference renvoie à la plus récente.

L'exemple suivant inclut un modèle d'expression régulière, (?<1>a)(?<1>\1b)*, qui redéfinit le groupe nommé \1. Le tableau suivant décrit chaque mode de l'expression régulière.

Modèle

Description

(?<1>a)

Mettre en correspondance le caractère « a » et assigner le résultat au groupe de capture nommé 1.

(?<1>\1b)*

Mettre en correspondance 0 ou 1 occurrence du groupe nommé 1 avec un « b » et assigner le résultat au groupe de capture nommé 1.

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

Lors de la comparaison de l'expression régulière avec la chaîne d'entrée (« aababb »), le moteur des expressions régulières exécute les opérations suivantes :

  1. Il commence au début de la chaîne, et met en correspondance « a » avec l'expression (?<1>a). La valeur du groupe 1 est maintenant « a ».

  2. Il avance jusqu'au deuxième caractère, et fait correspondre la chaîne « ab » avec l'expression \1b ou « ab ». Il assigne ensuite le résultat, « ab » à \1.

  3. Il avance jusqu'au quatrième caractère. L'expression (?<1>\1b) sera mise en correspondance aucune ou plusieurs fois, pour que la chaîne « abb » corresponde à l'expression \1b. Il réassigne le résultat, « abb », à \1.

Dans cet exemple, * un quantificateur en boucle -- il est évalué à plusieurs reprises jusqu'à ce que le moteur des expressions régulières ne puisse pas correspondre au modèle qu'il définit. Les quantifieurs en boucle ne suppriment pas les définitions de groupe.

Si un groupe n'a capturé aucune sous-chaîne, une backreference à ce groupe n'est pas définie et ne trouve aucune correspondance. Cela est illustré par le modèle d'expression régulière \b(\p{Lu}{2})(\d{2})?(\p{Lu}{2})\b, défini comme suit :

Modèle

Description

\b

Commencer la correspondance à la limite d'un mot.

(\p{Lu}{2})

Mettre en correspondance deux lettres majuscules. Il s'agit du premier groupe de capture.

(\d{2})?

Mettre en correspondance zéro ou une occurrence de deux chiffres décimaux. Il s'agit du deuxième groupe de capture.

(\p{Lu}{2})

Mettre en correspondance deux lettres majuscules. Il s'agit du troisième groupe de capture.

\b

Terminez la correspondance sur la limite d'un mot.

Une chaîne d'entrée peut correspondre à cette expression régulière même si les deux chiffres décimaux définis par le deuxième groupe de capture ne sont pas présents. L'exemple suivant montre que, bien que la correspondance soit réussie, un groupe de capture vide est trouvé entre deux groupes de capture réussis.

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

Voir aussi

Concepts

Éléments du langage des expressions régulières