Regex : drapeau sticky "y", recherche à une position
Découvrez le drapeau sticky (y) dans les expressions régulières JavaScript : comment il ancre la recherche à lastIndex et diffère du drapeau global (g).
Le drapeau y — le drapeau sticky — est l'un des drapeaux que vous pouvez ajouter à une expression régulière JavaScript. Il ancre chaque recherche à une position exacte : le lastIndex de l'expression régulière. Si une correspondance ne peut pas commencer exactement à lastIndex, la correspondance échoue — le moteur ne recherche pas plus loin.
Cette page explique ce que fait le drapeau sticky, en quoi il diffère du drapeau global (g), comment lastIndex est lu et mis à jour, les pièges courants, et où ce drapeau est véritablement utile (tokeniseurs et parseurs séquentiels).
Le concept du drapeau sticky (y)
Le drapeau sticky (y) garantit que la correspondance commence exactement à l'index stocké dans la propriété lastIndex de l'objet expression régulière. C'est le contraste principal avec le drapeau global (g) : g laisse le moteur avancer à partir de lastIndex pour trouver la prochaine correspondance n'importe où plus loin dans la chaîne, tandis que y exige que la correspondance commence à lastIndex ou pas du tout. Ce comportement "sans avance" est exactement ce dont un tokeniseur a besoin — il garantit que l'entrée est consommée de manière contiguë, sans lacunes inattendues entre les tokens.
y n'avance pas — g le fait
La façon la plus claire de voir la différence est de donner aux deux drapeaux un motif qui ne correspond pas à la position 0 :
Le drapeau g trouve abc même si cela commence à l'index 3. Le drapeau y retourne null, car la position 0 contient un ., et non le début de abc.
Dans l'exemple ci-dessus, le drapeau y garantit que le deuxième appel à test commence la correspondance à la position immédiatement après la correspondance précédente. Deux détails méritent d'être notés :
- Une correspondance réussie fait avancer
lastIndexjusqu'à l'index juste après la correspondance (0 → 3 → 6). Cette avance automatique permet d'appelertest/execdans une boucle. - Une correspondance échouée réinitialise
lastIndexà 0. Après que le troisième appel retournefalse,lastIndexrevient à 0, prêt à recommencer.
lastIndex est à la fois lu et écrit
lastIndex n'est pas simplement une entrée que vous définissez — le moteur le met à jour à chaque appel test/exec utilisant y (ou g). Le schéma habituel est donc : définir lastIndex une fois si vous souhaitez commencer ailleurs qu'à 0, puis laisser la boucle le gérer.
Le drapeau sticky affecte aussi les ancres
Avec le drapeau y, l'ancre de début de chaîne ^ n'est pas réancrée à lastIndex — ^ signifie toujours "début de la chaîne entière" (ou début de ligne avec le drapeau m). Le comportement sticky provient de la règle implicite "correspondance à lastIndex", et non d'une réécriture de ^. Ainsi, un motif comme /^x/y échouera à tout lastIndex supérieur à 0, car ^ ne peut jamais être satisfait là.
Applications pratiques du drapeau sticky
Analyse de flux de données
Le drapeau sticky est particulièrement avantageux pour analyser des flux de données où vous devez faire correspondre des tokens de manière séquentielle.
Tokenisation de chaînes
Un autre cas d'usage courant est la tokenisation de chaînes, où vous devez vous assurer que le tokeniseur progresse d'une correspondance à l'autre sans sauter de caractères.
Recherche à une position spécifique
La propriété lastIndex de JavaScript combinée au drapeau sticky peut être utilisée pour rechercher des motifs à partir d'une position spécifique dans une chaîne.
Dans cet exemple, définir lastIndex à 6 permet à la méthode test de trouver le mot "world" à partir de la position spécifiée.
Combinaison du drapeau sticky avec d'autres drapeaux
Le drapeau sticky peut être combiné avec d'autres drapeaux comme g (global) pour améliorer les capacités de correspondance de motifs. Dans cet exemple, le drapeau g permet une recherche globale dans toute la chaîne, tandis que le drapeau y garantit que chaque correspondance commence exactement à la position lastIndex. Cette combinaison permet d'effectuer une recherche globale avec le comportement de correspondance séquentielle stricte du drapeau sticky.
Dans cet exemple, nous avons mis à jour l'expression régulière pour consommer le délimiteur virgule. Cela garantit que la prochaine correspondance commence à la bonne position sans manipulation manuelle d'index.
Exemples avancés
Extraction de paires clé-valeur
Considérons un scénario plus complexe où vous devez extraire des paires clé-valeur d'une chaîne avec différents séparateurs. Chaque partie de la paire est extraite avec un groupe de capture — match[1] est la clé et match[3] est la valeur.
Analyse de journaux
Le drapeau sticky peut être extrêmement utile pour analyser des journaux structurés où les entrées doivent être mises en correspondance à partir de positions spécifiques.
Notez que le groupe de message est [^;]+ ("tout jusqu'au prochain ;") plutôt que \w+. Avec \w+, un message contenant un espace arrêterait la correspondance en plein milieu de l'entrée ; comme le drapeau sticky refuse d'avancer, le prochain appel à exec échouerait et la boucle se terminerait prématurément — abandonnant silencieusement les entrées restantes. C'est le piège le plus courant du drapeau sticky : votre motif doit consommer l'entrée de manière contiguë, sinon l'analyse s'arrête net.
Quand utiliser y (et quand ne pas l'utiliser)
Utilisez le drapeau sticky lorsque :
- Vous écrivez un tokeniseur ou un parseur et avez besoin de consommer l'entrée de manière contiguë, un token à la fois, sans lacunes autorisées.
- Vous souhaitez tester si un motif correspond à une position exacte, sans que le moteur aille chercher une correspondance plus loin dans la chaîne.
Préférez le simple drapeau global (g) lorsque vous voulez simplement toutes les correspondances n'importe où dans la chaîne et que vous ne vous souciez pas qu'elles soient adjacentes — par exemple, trouver toutes les adresses e-mail dans un document.
N'oubliez pas les deux règles qui causent la plupart des bugs liés au drapeau sticky : une correspondance échouée réinitialise lastIndex à 0, et votre motif doit consommer chaque caractère entre les correspondances ou la boucle s'arrête prématurément.
Conclusion
Le drapeau sticky (y) échange la commodité "chercher n'importe où" de g contre une correspondance stricte et positionnelle à lastIndex. Ce compromis est exactement ce que vous souhaitez lors de la création de tokeniseurs et de parseurs séquentiels, où la consommation contiguë est importante. Combinez-le avec des groupes de capture pour extraire des données structurées, et surveillez lastIndex — une fois que vous comprenez comment il avance et se réinitialise, la correspondance sticky devient un outil précis et prévisible.
Sujets connexes
- Motifs et drapeaux
- Ancres : début
^et fin$de chaîne - Groupes de capture
- Les expressions régulières en JavaScript