Nous pouvons utiliser le contenu des groupes de capture (...)
non seulement dans le résultat ou dans la chaîne de caractères de remplacement, mais également dans le pattern en lui-même.
Rétro référence par un nombre : \N
Un groupe peut être référencé dans le pattern par \N
, où N
est le numéro du groupe.
Pour rendre son utilité claire, considérons la tâche ci-dessous.
Nous devons trouver des chaînes citées : soit par des apostrophes '...'
, soit par des guillemets "..."
– les deux variantes devraient correspondre.
Comment les trouver ?
Nous pouvons mettre les deux types entre crochets : ['"](.*?)['"]
, mais ce pattern pourrait correspondre avec des mélanges comme "...'
ou '..."
. Cela mènerait à des correspondances incorrectes lorsqu’une citation apparaît dans une autre, comme dans le texte "She's the one!"
:
let str = `He said: "She's the one!".`;
let regexp = /['"](.*?)['"]/g;
// Le résultat n'est pas celui que nous aimerions avoir
alert( str.match(regexp) ); // "She'
Comme nous pouvons le voir, le pattern trouve des guillemets ouvrant "
, puis le texte est récupéré jusqu’au '
, ce qui termine la correspondance.
Pour faire en sorte que le pattern vérifie que le caractère terminant la citation est précisément le même que celui qui l’ouvre, nous pouvons l’envelopper dans un groupe de capture et le rétro référencier : (['"])(.*?)\1
.
Voilà le code correct :
let str = `He said: "She's the one!".`;
let regexp = /(['"])(.*?)\1/g;
alert( str.match(regexp) ); // "She's the one!"
Maintenant, ça fonctionne ! Le moteur trouve le premier caractère de citation (['"])
et mémorise son contenu. C’est le premier groupe de capture.
Plus loin dans le pattern, \1
signifie “cherche le même texte que dans le premier groupe de capture”, le même caractère de citation dans notre cas.
Similairement, \2
voudrait référencier le 2nd groupe, \3
– le 3e groupe, et ainsi de suite.
Si nous utilisons ?:
dans le groupe, alors nous ne pouvons pas le référencer. Les groupes exclus de la capture (?:...)
ne sont pas mémorisés par le moteur.
\1
, dans le replacement : $1
Dans la chaîne de remplacement, on utilise un signe dollar : $1
, alors que dans un pattern – un antislash \1
.
Rétro référence par le nom: \k<name>
Si une expression régulière a beaucoup de groupes, il est pratique de leur attribuer un nom.
Pour référencer un groupe nommé, on peut utiliser \k<name>
.
Dans l’exemple ci-dessous, le groupe du caractère de citation s’appelle ?<quote>
, donc la rétro référence est \k<quote>
:
let str = `He said: "She's the one!".`;
let regexp = /(?<quote>['"])(.*?)\k<quote>/g;
alert( str.match(regexp) ); // "She's the one!"