You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 9-regular-expressions/16-regexp-sticky/article.md
+15-15Lines changed: 15 additions & 15 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,30 +1,30 @@
1
1
2
-
# Sticky flag "y", recherche depuis une position
2
+
# Marqueur collant "y", recherche depuis une position
3
3
4
-
Le marqueur `pattern:y` permet d'effectuer la recherche à partir d'une position donnée dans la chaîne de caractères source.
4
+
Le marqueur `pattern:y` permet d'effectuer une recherche à partir d'une position donnée dans la chaîne de caractères source.
5
5
6
-
Pour appréhender le cas d'usage du marqueur `pattern:y`, et mieux comprendre le fonctionnement des regexp, regardons un exemple pratique.
6
+
Pour appréhender le cas d'usage du marqueur `pattern:y` et mieux comprendre le fonctionnement des regexps, regardons un exemple pratique.
7
7
8
-
Prenons un usage courant des regexps, l'analyse lexicale : Nous avons un texte, p. ex. dans un langage de programmation, et nous avons besoin de trouver ses éléments de structure. Par exemple, l'HTML a des balises et des attributs, du code JavaScript a des fonctions, variables, etc.
8
+
Parmi les usages courants des regexps, l'analyse lexicale : Avec un texte donné, p. ex. dans un langage de programmation, nous avons besoin de trouver ses éléments de structure. Par exemple, l'HTML a des balises et des attributs, le code JavaScript a des fonctions, variables, etc.
9
9
10
10
L'écriture d'analyseurs lexicaux est un domaine spécifique, avec ses propres outils et algorithmes que nous n'explorerons pas ici, mais il y a une tâche courante : Lire quelque chose depuis une position donnée.
11
11
12
12
P. ex. prenons la chaîne de caractères `subject:let varName = "value"`, dans laquelle nous devons lire le nom de la variable, qui commence à la position `4`.
13
13
14
-
Nous chercherons un nom de variable en utilisant la regexp `pattern:\w+`. En fait, les noms de variable en JavaScript nécessitent une regexp un poil plus complexe pour un résultat exact, mais cela est sans importance ici.
14
+
Nous chercherons un nom de variable en utilisant la regexp `pattern:\w+`. Les noms de variable en JavaScript nécessitent en fait pour un résultat exact, une regexp un peu plus complexe, mais c'est sans importance ici.
15
15
16
16
- Un appel à `str.match(/\w+/)` trouvera seulement le premier mot de la ligne (`let`). Ça n'est pas ça.
17
-
- Nous pouvons ajouter le marqueur `pattern:g`. Mais alors l'appel à `str.match(/\w+/g)` cherchera tous les mots du text, alors que nous avons besoin que d'un mot à partir de la position `4`. Ça n'est pas encore ça.
17
+
- Nous pouvons ajouter le marqueur `pattern:g`. Mais alors l'appel à `str.match(/\w+/g)` cherchera tous les mots du text, alors que nous avons besoin que d'un mot à partir de la position `4`. Ça n'est donc pas encore ça.
18
18
19
-
**Alors comment rechercher un motif à partir d'une position donné ?**
19
+
**Alors comment rechercher un motif à partir d'une position donnée ?**
20
20
21
21
Essayons en utilisant la méthode `regexp.exec(str)`.
22
22
23
23
Pour une `regexp` sans marqueur `pattern:g` ni `pattern:y`, cette méthode cherche seulement la première occurrence, cela fonctionne exactement comme `str.match(regexp)`.
24
24
25
-
...Mais s'il y a le marqueur `pattern:g`, il effectue alors une recherche dans `str`, à partir de la position stockée dans propriété `regexp.lastIndex`. Et s'il trouve une correspondance, il fixe `regexp.lastIndex` à l'index immédiatement après la correspondance.
25
+
...Mais s'il y a le marqueur `pattern:g`, il effectue alors une recherche dans `str`, à partir de la position stockée dans la propriété `regexp.lastIndex`. Et s'il trouve une correspondance, il fixe `regexp.lastIndex` à l'index immédiatement après cette correspondance.
26
26
27
-
En d'autres termes, `regexp.lastIndex` sert de point de départ pour la recherche, que chaque appel à `regexp.exec(str)` change en une nouvelle valeur ("après la dernière correspondance"). Cela, bien entendu, seulement avec le marquer `pattern:g`.
27
+
En d'autres termes, `regexp.lastIndex` sert de point de départ pour la recherche, puis chaque appel à `regexp.exec(str)`la change en une nouvelle valeur ("après la dernière correspondance"). Cela, bien entendu, uniquement avec le marquer `pattern:g`.
28
28
29
29
Donc chaque appel successif à `regexp.exec(str)` retourne une correspondance après l'autre.
30
30
@@ -42,14 +42,14 @@ alert(regexp.lastIndex); // 3 (position après la première correspondance)
42
42
43
43
let word2 =regexp.exec(str);
44
44
alert(word2[0]); // varName (2e mot)
45
-
alert(regexp.lastIndex); // 11 (position après la correspondance)
45
+
alert(regexp.lastIndex); // 11 (position après la seconde correspondance)
alert(regexp.lastIndex); // 0 (réinitialisé à la fin de la recherche)
50
50
```
51
51
52
-
Nous pouvons obtenir toutes les correspondances avec la boucle :
52
+
Nous pouvons ainsi obtenir toutes les correspondances dans la boucle :
53
53
54
54
```js run
55
55
let str ='let varName';
@@ -93,7 +93,7 @@ Le résultat est valide.
93
93
94
94
...Mais attendez, pas si vite.
95
95
96
-
Vous noterez : l'appel à `regexp.exec` commence la recherche à la position `lastIndex` et continue ensuite plus loin. S'il n'y a pas de mot à la position `lastIndex`, mais qu'il y en a un plus loin, il sera alors trouvé :
96
+
Vous noterez : l'appel à `regexp.exec` commence la recherche à la position `lastIndex` et continue ensuite plus loin. S'il n'y a pas de mot à la position `lastIndex`, mais qu'il y en a un plus loin, c'est celui-ci qui sera trouvé :
97
97
98
98
```js run
99
99
let str ='let varName = "value"';
@@ -111,7 +111,7 @@ alert(word[0]); // varName
111
111
alert(word.index); // 4
112
112
```
113
113
114
-
Pour certaines tâches, et pour les analyses lexicales en particulier, c'est juste faux. Nous avons besoin de trouver la correspondance du motif à la position exacte, et non quelque part après. Et c'est justement ce que fait le marqueur `y`.
114
+
Pour certaines tâches, et pour les analyses lexicales en particulier, c'est complètement faux. Nous avons besoin de trouver la correspondance du motif à la position exacte, et non quelque part plus loin. Et c'est justement ce que fait le marqueur `y`.
115
115
116
116
**Le marqueur `pattern:y` fait que `regexp.exec` recherche exactement à la position `lastIndex`, et non à partir de cette position.**
117
117
@@ -131,8 +131,8 @@ alert( regexp.exec(str) ); // varName (mot en position 4)
131
131
132
132
Comme nous pouvons le voir, la regexp `pattern:/\w+/y` ne trouve pas de correspondance en position `3` (contrairement au marqueur `pattern:g`), mais trouve la correspondance en position `4`.
133
133
134
-
Et en plus d'obtenir ce que nous cherchions, mais il y a un gain significatif de performance avec le marqueur `pattern:y`.
134
+
En plus d'obtenir ce que nous cherchions, il y a un gain significatif de performance avec le marqueur `pattern:y`.
135
135
136
-
Imaginez avec un long texte, et sans aucune correspondance dedans. Une recherche avec le marqueur `pattern:g` ira alors jusqu'à la fin du texte pour ne rien trouver, et cela prendra bien plus de temps qu'avec le marqueur `pattern:y`, qui vérifie seulement à la position exacte.
136
+
Imaginez avec un long texte, sans aucune correspondance dedans. Une recherche avec le marqueur `pattern:g` ira alors jusqu'à la fin du texte pour ne rien trouver, et cela prendra bien plus de temps qu'avec le marqueur `pattern:y`, qui vérifie seulement à la position exacte.
137
137
138
138
Dans des tâches comme en analyse lexicale, il y a habituellement beaucoup de recherches sur des positions exactes, pour vérifier ce qu'il s'y trouve. L'utilisation du marqueur `pattern:y` est la clé pour des bonnes implémentations et de bonnes performances.
0 commit comments