Parfois nous avons juste besoin de trouver les motifs précédents ou suivant un autre motif.
Il existe pour cela des syntaxes spéciales, appelées “lookahead” et “lookbehind”, ensemble désignées par “lookaround”.
Pour commencer, trouvons le prix à partir d’une chaîne de caractères comme sujet:1 dindes coûte 30€
.C’est un nombre suivi par le signe sujet:€
Lookahead
La syntaxe est: X(?=Y)
, cela veut dire “recherche X
, mais renvoie une correspondance seulement si il est suivi de Y
”. Tous les motifs peuvent être utilisés au lieu de X
et Y
.
Pour un nombre entier suivi de sujet:€
, l’expression régulière sera \d+(?=€)
:
let str = "1 dinde coûte 30€";
alert( str.match(/\d+(?=€)/) ); // 30, le nombre 1 est ignoré, vu qu'il n'est pas suivi de €
NB: Le lookahead est seulement un test, le contenu de la parenthèse (?=...)
n’est pas include dans le resultat 30
.
Quand nous recherchons X(?=Y)
, le moteur d’expressions régulières trouve X
et verifie s’il y a Y
immediatemment après. Si ce n’est pas le cas, la correspondqnce possible est ignoré, et la recherche continue.
Des tests plus complexes sont possibles, ex: X(?=Y)(?=Z)
signifie:
- Trouve
X
. - Verifier si
Y
est immédiatement aprèsX
(ignorer sinon). - Verifier si
Z
se situe aussi immédiatement aprèsX
(ignorer sinon)… - Si les deux tests sont réussis, alors le motif
X
correspond, sinon continuer à chercher.
En d’autres mots, ce genre de motif signifie que nous recherchons X
suivi de Y
et Z
en meme temps
C’est possible seulement si Y
et Z
ne s’excluent pas mututellement.
Par exemple, \d+(?=\s)(?=.*30)
recherche \d+
suivi du motif (?=\s)
, et il y a 30
quelque part apres lui (?=.*30)
:
let str = "1 dinde coute 30€";
alert( str.match(/\d+(?=\s)(?=.*30)/) ); // 1
Dans notre chaîne de caractères cela correspond exactement au nombre 1
.
Lookahead negatif
Supposons que nous recherchons plutôt une quantité, non un prix, a partir de la même chaîne de caractères.
Pour cela, le lookahead negatif peut etre utilisé.
La syntaxe est: X(?!Y)
, cela veut dire X
, mais seulement si il n’est pas suivi de Y
".
let str = "2 turkeys cost 60€";
alert( str.match(/\d+\b(?!€)/g) ); // 2 (le prix ne correspond pas au motif)
Lookbehind
Veuillez noter : Lookbehind n’est pas pris en charge dans les navigateurs non-V8, tels que Safari, Internet Explorer.
Lookahead permet d’ajouter une condition sur “ce qui suit”.
Lookbehind est similaire a lookahead, mais il regarde derrière.Ça veut dire qu’il établit une correspondance seulement si il y a quelquechose avant lui,
La syntaxe est:
- Lookbehind positif:
(?<=Y)X
, correspond àX
, mais seulement si il y aY
avant lui. - Lookbehind negatif:
(?<=Y)X
, correspond àX
, mais seulement si il n’y a pasY
avant lui.
Pqr exemple,changeons le prix en dollars US. Le signe dollar est généralement placé avant le chiffre,donc pour recupérer $30
nous utiliserons(?<=\$)\d+
– Une quantité précédé de $
:
let str = "1 turkey costs $30";
// le signe dollar est echappé \$
alert( str.match(/(?<=\$)\d+/) ); // 30 (ignore le nombre sans dollar)
Et si nous avons besoin d’une quantité – un nombre non précédé de $
, alors nous pouvons utiliser un lookbehind négatif (?<!\$)\d+
:
let str = "2 dndes coûte $60";
alert( str.match(/(?<!\$)\b\d+/g) ); // 2 (le prix ne correspond pas )
Groupes capturants
Généralement, le contenu d’une parenthese de lookaround ne fait partie des resultats.
Par exmple dans le motif \d+(?=€)
, le signe €
n’est pas capture comme une partie de la corredpondance. C’est naturel: nous recherchons un nombre \d+
, tandis que (?=€)
iest juste un test qui doit etre suivi de €
.
Mais dans certains cas, nous voulons capturer l’expression du lookaround aussi, comme une partie de la correspondance.C’est possible.Il suffit juste de le l’entourer d’une parenthese supplementaire.
Dans l’exemple suivant, le signe de la monnaie est capture, en meme temps aue la quqntite.
let str = "1 turkey costs 30€";
let regexp = /\d+(?=(€|kr))/; // parentheses supplemetaires autour de €|kr
alert( str.match(regexp) ); // 30, €
Et voila le meme chose pour lookbehind:
let str = "1 turkey costs $30";
let regexp = /(?<=(\$|£))\d+/;
alert( str.match(regexp) ); // 30, $
Summary
Lookahead et lookbehind (ensemble désignés sous le nom de lookaround) sont utiles quand nous voulons identifier quelquechose selon le contexte avant/après lui.
Pour les expressions regulières simple, nous pouvons une chose similaire manuellement: considerer tous les elemets, dans tous les contextes et alors filtrer par contexte en boucle
Vous vous souvenez que str.match
(sans le drapeau g
) et str.matchAll
retournent (toujours) les correspondances comme des tableaux avec une propriete index
, et donc nous connaissons où exactement il est et nous pouvons verifier le contexte
Mais generalement lookaround est plus adapté.
Types de lookaround:
motif | type | correspondances |
---|---|---|
X(?=Y) |
Lookahead positif | X si il est suivi de Y |
X(?!Y) |
Lookahead négatif | X si il n’est pas suivi deY |
(?<=Y)X |
Lookbehind positif | X s’il suit Y |
(?<!Y)X |
Lookbehind négatif | X s’il ne suit pas Y |
Commentaires
<code>
, pour plusieurs lignes – enveloppez-les avec la balise<pre>
, pour plus de 10 lignes - utilisez une sandbox (plnkr, jsbin, codepen…)