Regular Expressions Références ambiguës


Exemple

Problème: Vous devez faire correspondre le texte d'un certain format, par exemple:

1-a-0
6/p/0
4 g 0

C'est un chiffre, un séparateur (un des - , / ou un espace), une lettre, le même séparateur et un zéro.

Solution naïve: en adaptant la regex à l' exemple de base , vous obtenez cette regex:

[0-9]([-/ ])[a-z]\10

Mais cela ne fonctionnera probablement pas. La plupart des versions de regex prennent en charge plus de neuf groupes de capture, et très peu d'entre elles sont suffisamment intelligentes pour comprendre que, puisqu'il n'y a qu'un groupe de capture, \10 doit être une référence au groupe 1 suivi d'un littéral 0 . La plupart des saveurs le traiteront comme une référence rétroactive au groupe 10. Quelques-unes d’entre elles lanceront une exception car il n’ya pas de groupe 10; le reste échouera tout simplement.

Il y a plusieurs façons d'éviter ce problème. L'une consiste à utiliser des groupes nommés (et des références nommées):

[0-9](?<sep>[-/ ])[a-z]\k<sep>0

Si votre langage regex le prend en charge, le format \g{n} (où n est un nombre) peut contenir le numéro de référence arrière entre accolades pour le séparer des chiffres suivants:

[0-9]([-/ ])[a-z]\g{1}0

Une autre méthode consiste à utiliser un format regex étendu, en séparant les éléments avec des espaces non significatifs (en Java, vous devrez échapper de l'espace entre crochets):

(?x) [0-9] ([-/ ]) [a-z] \1 0

Si votre version regex ne prend pas en charge ces fonctionnalités, vous pouvez ajouter une syntaxe inutile mais inoffensive, comme un groupe non capturant:

[0-9]([-/ ])[a-z](?:\1)0

... ou un quantificateur factice (c'est peut-être la seule circonstance où {1} est utile):

[0-9]([-/ ])[a-z]\1{1}0