Assertions

Les assertions indiquent les conditions selon lesquelles il est possible d'avoir une correspondance (contenu situé avant la correspondance, situé après ou expressions conditionnelles).

Types

Note : Le caractère ? peut également être utilisé comme quantificateur.

Caractères Signification
x(?=y)

Correspond à 'x' seulement s'il est suivi de 'y'. On appelle cela un test de succession (lookahead).

Ainsi, /Jack(?=Sparrow)/ correspond à 'Jack' seulement s'il est suivi de 'Sparrow'. /Jack(?=Sparrow|Bauer)/ correspond à 'Jack' seulement s'il est suivi de 'Sparrow' ou de 'Bauer'. Cependant, ni 'Sparrow' ni 'Bauer' ne feront partie de la correspondance.

x(?!y)

Correspond à 'x' seulement si 'x' n'est pas suivi de 'y'.

Ainsi, /\d+(?!\.)/ correspond à un nombre qui n'est pas suivi par un point, cette expression utilisée avec la chaîne 3.141 correspondra pour '141' mais pas pour '3.141'.

(?<=y)x

Correspond à x seulement si x est précédé par y. C'est ce qu'on appelle une recherche arrière (lookbehind).

Ainsi /(?<=Jack)Sprat/ correspond à "Sprat" seulement s'il est précédé de "Jack".
/(?<=Jack|Tom)Sprat/ correspond à "Sprat" seulement s'il est précédé de "Jack" ou "Tom".
Toutefois, "Jack" et "Tom" ne feront pas partie de la correspondance.

(?<!y)x

Correspond à x uniquement si x n'est pas précédé par y (parfois appelée en anglais negated lookbehind).

Ainsi, /(?<!-)\d+/ correspondra à un nombre seulement si celui-ci n'est pas précédé d'un signe moins.
/(?<!-)\d+/.exec('3') cible "3".
/(?<!-)\d+/.exec('-3') ne trouve aucune correspondance car le nombre est précédé d'un signe

Exemples

Assertion avant (lookahead)

js
let regex = /Premier(?= test)/g;

console.log("Premier test".match(regex)); // [ 'Premier' ]
console.log("Premier truc".match(regex)); // null
console.log("Voici le Premier test de l'année.".match(regex)); // [ 'Premier' ]
console.log("Voici le Premier truc du mois.".match(regex)); // null

Assertion avant négative

L'expression rationnelle /\d+(?!\.)/ permettra de rechercher plusieurs chiffres si ceux-ci ne sont pas suivis d'un point décimal. Ainsi, /\d+(?!\.)/.exec('3.141') trouvera la sous-chaîne "141" mais pas "3."

js
console.log(/\d+(?!\.)/g.exec("3.141")); // [ '141', index: 2, input: '3.141' ]

Signification différente de '?!' entre les assertions et les intervalles

La combinaison de caractères ?! a un sens différent entre les assertions /x(?!y)/ et les intervalles [^?!].

js
let orangePasCitron =
  "Voulez-vous avoir une orange? Oui, je ne veux pas avoir de citron!";

let choixPasCitron = /[^?!]+avoir(?! un citron)[^?!]+[?!]/gi;
console.log(orangePasCitron.match(choixPasCitron)); // [ 'Voulez-vous avoir une orange?' ]

let choixPasOrange = /[^?!]+avoir(?! une orange)[^?!]+[?!]/gi;
console.log(orangePasCitron.match(choixPasOrange)); // [ 'Oui, je ne veux pas avoir de citron!' ]

Assertion arrière (lookbehind)

js
let oranges = ["espèce orange A ", "sorte orange B", "espèce orange C"];

let especesOranges = oranges.filter((fruit) =>
  fruit.match(/(?<=espèce )orange/),
);
console.log(especesOranges); // [ 'espèce orange A ', 'espèce orange C' ]