Comment les groupes non capturants, c'est-à-dire "(? :)`", sont-ils utilisés dans les expressions régulières et à quoi servent-ils ?
?:
est utilisé lorsque vous voulez grouper une expression, mais que vous ne voulez pas l'enregistrer en tant que partie de la chaîne de caractères correspondant à l'expression ou capturée.
Un exemple serait une expression pour faire correspondre une adresse IP :
/(?:\d{1,3}\.){3}\d{1,3}/
Notez que je ne me soucie pas de sauvegarder les 3 premiers octets, mais le groupement (? :...)
me permet de raccourcir la regex sans encourir la surcharge de capturer et de stocker une correspondance.
Il rend le groupe non capturant, ce qui signifie que la sous-chaîne correspondant à ce groupe ne sera pas incluse dans la liste des captures. Un exemple en ruby pour illustrer la différence :
"abc".match(/(.)(.)./).captures #=> ["a","b"]
"abc".match(/(?:.)(.)./).captures #=> ["b"]
Les groupes qui captent peuvent être utilisés plus tard dans la regex pour correspondre OU vous pouvez les utiliser dans la partie de remplacement de la regex. La création d'un groupe non capturant exempte simplement ce groupe d'être utilisé pour l'une ou l'autre de ces raisons.
Les groupes non capturables sont très utiles si vous essayez de capturer plusieurs choses différentes et qu'il y a des groupes que vous ne voulez pas capturer.
C'est à peu près la raison de leur existence. Pendant que vous vous renseignez sur les groupes, apprenez à connaître les [Groupes atomiques][1], ils font beaucoup de choses ! Il existe également des groupes de contournement, mais ils sont un peu plus complexes et moins utilisés.
Exemple d'utilisation ultérieure dans la regex (backreference) :
<([A-Z][A-Z0-9]*)\b[^>]*>.*?</\1>
[ Trouve une balise xml (sans support ns) ].
([A-Z][A-Z0-9]*)
est un groupe de capture (dans ce cas, c'est le tagname)
Plus loin dans l'expression, on trouve \1
, ce qui signifie qu'elle ne correspondra qu'au même texte que dans le premier groupe (le groupe ([A-Z][A-Z0-9]*)
) (dans ce cas, il s'agit de la balise de fin).