Guides1 chasse jouable incluse

Les références arrière en regex : des motifs qui se souviennent de ce qu'ils ont trouvé

Une référence arrière comme \1 correspond exactement au texte qu'un groupe a déjà capturé. Voici comment elles fonctionnent, comment trouver les lettres doublées, les mots répétés et les palindromes, et le seul endroit où elles ne marchent pas.

Logo de Regex Hunter

· 7 min de lecture

/(.)\1/

à attraper

  • book
  • letter
  • coffee

à épargner

  • cat
  • dog
  • lemon

L'essentiel d'une regex décrit des types de texte : un chiffre, une lettre, n'importe quel caractère. Une référence arrière (backreference) est différente. Elle dit « le même texte que celui que je viens de trouver ». Cette seule idée permet à un motif court de repérer des lettres doublées, des mots répétés et des palindromes, ce qu'aucune classe de caractères ne sait décrire.

Tous les exemples ci-dessous sont interactifs. Modifiez le motif, ou cliquez sur Essayer pour l'ouvrir dans le bac à sable.

01D'abord capturer, ensuite y faire référence

Les parenthèses ont deux rôles : elles regroupent, et elles capturent. Le texte trouvé par un groupe est mémorisé, et les groupes sont numérotés de gauche à droite selon leur parenthèse ouvrante. \1 signifie « le texte capturé par le groupe 1 », \2 celui du deuxième groupe, et ainsi de suite.

Correspondances6/6 comme prévu
/(.)\1/

Doit correspondre3/3

  • book
  • letter
  • coffee

Ne doit pas3/3

  • cat
  • dog
  • lemon
Essayez-le dans le bac à sable
(.) capture un caractère, et \1 redemande ce même caractère. Toute lettre doublée correspond.

Le mot clé, c'est même texte. (\w)\w signifie « une lettre, puis n'importe quelle lettre », donc ça correspond à presque tout. (\w)\1 signifie « une lettre, puis exactement cette lettre à nouveau ». La référence arrière ne répète pas le motif du groupe. Elle en répète le résultat.

02Mots répétés

Un grand classique de la relecture, c'est le mot doublé : « the the ». Capturez un mot, puis demandez un espace suivi du même mot :

Correspondances4/4 comme prévu
/\b(\w+) \1\b/

Doit correspondre2/2

  • this is the the end
  • it is is fine

Ne doit pas2/2

  • the then
  • that is it
Essayez-le dans le bac à sable
Le \b à chaque extrémité limite la recherche aux mots entiers, donc « the then » ne compte pas comme deux « the ».

Sans le \b final, the then correspondrait : the, un espace, puis le the au début de then.

03Commencer et finir par la même lettre

Des ancres et une référence arrière ensemble décrivent la forme d'un mot :

Correspondances6/6 comme prévu
/^(.).*\1$/

Doit correspondre4/4

  • level
  • radar
  • stats
  • noon

Ne doit pas2/2

  • hello
  • regex
Essayez-le dans le bac à sable
La première lettre est capturée, .* saute le milieu, et \1$ exige la même lettre tout à la fin.

04Palindromes de cinq lettres

Avec deux groupes, on peut créer un miroir. Capturez les deux premières lettres, autorisez n'importe quelle lettre au milieu, puis exigez-les à nouveau dans l'ordre inverse :

Correspondances6/6 comme prévu
/^(.)(.).\2\1$/

Doit correspondre4/4

  • level
  • radar
  • kayak
  • refer

Ne doit pas2/2

  • hello
  • lever
Essayez-le dans le bac à sable
Le groupe 1 doit revenir en dernier et le groupe 2 en avant-dernier, donc le mot se lit pareil dans les deux sens.

lever n'est pas loin : il commence par le, mais finit par er, pas par el.

05Des guillemets qui vont par paires

Une référence arrière peut garantir que le guillemet fermant correspond à l'ouvrant. (["']) capture l'un ou l'autre type de guillemet, et \1 referme avec le même :

Correspondances2/2 comme prévu
/(["']).*?\1/
  • He said "it's fine"
  • 'single' and "double"
Essayez-le dans le bac à sable
L'apostrophe de it's ne termine pas la première correspondance, car la chaîne a été ouverte par un guillemet double.

06Groupes nommés

Les numéros deviennent vite difficiles à suivre dans un long motif. La plupart des moteurs permettent de nommer un groupe et d'y faire référence par son nom :

Motif14 car.
/(?<ch>.)\k<ch>/
Essayez-le dans le bac à sable
La même détection de lettre doublée que (.)\1, avec un groupe nommé « ch ».

La syntaxe varie selon les langages. JavaScript, .NET et PCRE utilisent (?<name>…) et \k<name>. Le module re intégré à Python utilise (?P<name>…) et (?P=name).

07Les références arrière dans les remplacements

Les groupes capturés sont tout aussi utiles quand vous remplacez du texte. Dans la plupart des éditeurs et des langages, vous pouvez réinsérer les groupes dans un nouvel ordre : cherchez (\w+), (\w+) et remplacez par $2 $1 (JavaScript, VS Code) ou \2 \1 (Python, sed) pour transformer Lovelace, Ada en Ada Lovelace.

08Le seul endroit où elles ne marchent pas : entre [ ]

On est tenté d'écrire (.)[^\1] pour dire « un caractère suivi d'un caractère différent ». Ça ne marche pas. Dans une classe de caractères, \1 n'est pas une référence arrière. En JavaScript, il est lu comme un code de caractère échappé, donc la classe signifie « tout sauf le caractère 1 » :

Correspondances2/2 comme prévu
Les deux lignes correspondent. [^\1] ne compare rien à la lettre capturée, donc « aa » passe.

Pour dire « pas le même caractère », utilisez un lookahead négatif : (.)(?!\1).. (Plus de détails dans notre guide du lookahead et du lookbehind.)

09À vous de jouer

Sur ce plateau, chaque monstre contient deux lettres doublées différentes, comme le ff et le ee de coffee. Chaque innocent n'en a qu'une :

Chasse jouablepar 12

Attrapez les mots qui ont deux lettres doublées.

Cibles · 0/5 attrapées

  • coffeecible
  • ballooncible
  • bookkeepercible
  • committeecible
  • mississippicible

Innocents · erreurs : 0

  • bookinnocent
  • letterinnocent
  • appleinnocent
  • grassinnocent
  • helloinnocent

Tapez une regex — le plateau se met à jour en direct.

Essayez-le dans le bac à sable
Ça vous plaît ? Une nouvelle chasse chaque jour.Jouer la chasse du jour

10Aide-mémoire

  • ( … ) capture. Les groupes sont numérotés selon leur parenthèse ouvrante.
  • \1, \2 … correspondent au même texte que celui capturé par le groupe, pas au même motif.
  • (?<name>…) avec \k<name> (JS, .NET, PCRE), ou (?P<name>…) avec (?P=name) (Python).
  • Dans les remplacements : $1 (JavaScript) ou \1 (Python, sed).
  • \1 entre [ ] n'est pas une référence arrière.

11Continuez à vous entraîner