Bonjour
Je débute en expressions régulières, j'écris une de la forme /a?|ab/g pour analyser le texte "aaab" j'obtiens alors un message d'erreur
"Allocation overflow" de dépassement de mémoire.Pourquoi?
Merci pour toute réponse.
Bonjour
Je débute en expressions régulières, j'écris une de la forme /a?|ab/g pour analyser le texte "aaab" j'obtiens alors un message d'erreur
"Allocation overflow" de dépassement de mémoire.Pourquoi?
Merci pour toute réponse.
Bonjour,
ce que tu nous montres comme code (en fait rien) est insuffisant pour que l'on puisse t'aider !
Les joies du CSS | Réponses sur forum | Simple comme JS | Essais libres autour de l'API G$$gle Maps
✂ ---------------------------------------------
developpez.net c'est aussi :
✔ Les meilleurs cours et tutoriels pour apprendre le CSS
✔ Les meilleurs cours et tutoriels pour apprendre le (X)HTML
✔ Les meilleurs cours et tutoriels pour apprendre le JavaScript
Bonjour, ça doit venir d'ailleurs...
si je fais /a?|ab/g.test("aaab") ça me renvoie true sur tout navigateur
voici le code d'essai qui m'a renvoyé l'erreur Allocation overflow
Merci
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 function test() { try { var regEx = /a|ab/g; var str = "aaab"; if(!regEx.test(str)) return null; var a = new Array(); regEx.lastIndex = 0; while((var result = regEx.exec(str)) != null) { a.push(result.index); } return a; } catch(exp) { alert(exp.message); } } //après j'essaie de récupérer le tableau des indexes s'il est non nulle et là j'obtiens l'erreur.
Salut
Code : Sélectionner tout - Visualiser dans une fenêtre à part if(!regEx.test(str)) {return null;}
:whistle:pourquoi pas, pour remercier, un :plusser: pour celui/ceux qui vous ont dépannés.
saut de ligne
OOOOOOOOO👉 → → Ma page perso sur DVP ← ← 👈
c'est normal tu lances une boucle while sur une condition qui ne change pas,
en effet si str ne change pas reg.test(str) ne sera jamais nul, ton tableau va se remplir sans fin ce qui déclenche le débordement de pile.
il faudrait faire un substr sur la chaine str quand le résultat est trouvé, pour sortir de la boucle.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 function test() { try { var regEx = /a|ab/g; var str = "aaab"; if(!regEx.test(str)) return null; var a = new Array(); var result; var o=0; while((result = regEx.exec(str)) != null) { a.push(result.index+o); str=str.substr(result.index+result[0].length); o+=result.index+result[0].length; } return a; } catch(exp) { alert(exp.message); }
Bonjour: En guise de réponse à 01001111
Je crois savoir que pour chaque appel à la méthode exect(str) sur regEx la position du curseur ou débute la recherche avance au caractère qui suit immédiatement le dernier caractère du dernier match et qui est indiquée par la propriété lastIndex et quand il n'y a plus de match la méthode retourne null et le curseur est réinitialisé à 0.La boucle while() devrait donc s'arrêter là. S'il n'y a pas de match du tout la methode retourne null dès le départ et la boucle n'est jamais déclenchée.
NB: Dans le code que j'ais donné j'ai oublié un ? dans le motif de la regEx en fait le motif qui declenche l'erreur est : /?a|ab/g et non /a|ab/g. Le motif est appliqué au texte "aaab" .C'est tout de même insignifiant mais c'est juste pour comprendre pourquoi cette erreur de dépassement de mémoire est declenchée.
Merci.
Je vois que la discussion a bien évolué pendant que j'étais occupé à diverses choses.
Je vous donne tout de même la solution que j'avais retenue hier soir :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 function test() { let regEx = /a|ab/g, str = "aaab", nb = str.length - 1, // -1 indispensable a = []; while (regEx.lastIndex < nb){ if (regEx.test(str)){ regEx.lastIndex--; // indispensable a.push(regEx.exec(str)); } } return a; } console.log(test()); /* (3) [Array(1), Array(1), Array(1)] 0: ["a", index: 0, input: "aaab", groups: undefined] 1: ["a", index: 1, input: "aaab", groups: undefined] 2: ["a", index: 2, input: "aaab", groups: undefined] length: 3 */
Blog
Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
(Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)
il te faut échapper le caractère « ? » pour que cela soit correct.Envoyé par Abdou_moujar
Code : Sélectionner tout - Visualiser dans une fenêtre à part var regEx = /\?a|ab/g;
Les joies du CSS | Réponses sur forum | Simple comme JS | Essais libres autour de l'API G$$gle Maps
✂ ---------------------------------------------
developpez.net c'est aussi :
✔ Les meilleurs cours et tutoriels pour apprendre le CSS
✔ Les meilleurs cours et tutoriels pour apprendre le (X)HTML
✔ Les meilleurs cours et tutoriels pour apprendre le JavaScript
Le motif ?a|ab n’est pas valide :
Par contre, si on regarde le motif donné dans le premier post, a?|ab, on peut le décomposer. a? signifie « a ou rien », c’est donc une sorte d’alternative : a|{rien}. (Bien sûr, la syntaxe {rien} n’existe pas, c’est juste pour être clair.)SyntaxError: nothing to repeat
On peut donc réécrire le motif en pseudo-regex : a|{rien}|ab.
Si on réordonne les alternatives : a|ab|{rien}
Et ça, ça peut se réécrire en vrai code valide : (a|ab)?
Et on peut même « factoriser le a : (ab?)?
Toutes les versions de cette regexp reconnaissent trois choses :
- "a"
- "ab"
- la chaîne vide ""
Important, il n’y a pas d’ancres (^ ou $) donc le motif peut correspondre à n’importe quel endroit d’une chaîne donnée. En particulier, la chaîne vide est reconnue partout, par exemple dans "xy" il y a une chaîne vide entre x et y. Par conséquent, cette regexp reconnaît toutes les chaînes.
Quand on utilise une regexp dans une boucle, il faut absolument vérifier qu’elle ne reconnaît pas la chaîne vide. En effet, la correspondance chaîne vide a une longueur 0, ce qui fait que lastIndex n’augmente pas, et exec fait du surplace.
Du coup, le script boucle, et selon le contexte, ça fait une popup qui dit « un script de la page ne répond plus », ou un dépassement de mémoire. En l’occurence, je pense que c’est l’allocation d’un nombre infini de variables result qui est la cause du message Allocation Overflow.
Même si c’est étrange, parce que chez moi (sous Firefox), je ne peux pas mettre un var dans un while, ça fait une SyntaxError. Du coup je ne peux faire que des hypothèses.
Certains outils, comme le site https://regexper.com/, te permettent de visualiser tes regexp sous la forme d’un graphe. Essaye a+b![]()
La FAQ JavaScript – Les cours JavaScript
Touche F12 = la console → l’outil indispensable pour développer en JavaScript !
Si on part de la pattern d'origine a?|ab, une pseudo-regex correspondante est a|{rien}|ab soit a|{rien} car toute alternative située après {rien} ne sera jamais testée, puisque {rien} réussit toujours. Donc pour simplifier la pattern de départ, on écrirait plutôt: a?.
Réordonner les alternatives en a|ab|{rien} sans changer le sens de la pattern de départ n'est ici possible que parce que a réussira toujours avant ab, on ne pourrait pas faire de même avec par exemple a|{rien}|bc. C'est pour la même raison qu'il n'y a pas de correspondance entre (a|ab)? et (ab?)? car la première pattern ne trouvera jamais la chaîne "ab" alors que la deuxième a la possibilité de le faire. (ab??)? (ou encore a?b??) serait plus fidèle mais peut se ramener quoi qu'il en soit à a?.
Salut
Pour la variable result en réalité je l'ai définie avant la boucle et non à l'intérieur comme je l'ai écrit dans le code. Donc aucun problème de ce coté là.
Mais revenons sur le motif /a?|ab/g appliqué à la chaine "aaab". Si j'utilise le motif /a+|ab/g ou le motif a|ab?/g ça marche à tous les coups. La boucle renvoie 3 matchs qui sont les 3 premières lettres 'a'. Mais analysons de près le motif qui pose problème.
Au départ lastIndex = 0 ce qui correspond à la première lettre 'a', il doit donc y avoir un premier match qui renvoie cette lettre et le curseur se place sur la deuxième lettre 'a' qui devrait à son tour être renvoyée et ainsi jusqu'à ce que le curseur se place sur la lettre 'b'. C'est là ou le comportement du motif n'est pas clair pour moi : est ce que a? veut dire a|{rien} ou bien veut dire a|{tout sauf a} c'est à dire en termes de motif a|[^a] A mon avis le curseur ne fait jamais du surplace car soit il avance lorsque un match est trouvé et dans ce cas result != null et la boucle continue, soit il est remis à 0 si aucun match n'est trouvé et dan ce cas result = null et la boucle s'achève. Tout ça demande peut être un peu plus d'éclaircissement. Le débat est donc toujours ouvert.
Merci pour toute participation.
@CosmoKnacki : merci pour ces éclaircissements
J’ai tendance à oublier l’aspect séquentiel des regexps, et à me dire que l’ordre n’est pas important.
Voilà qui me rassure
Et ce que je n’avais pas vu jusqu’à maintenant, c’est le a.push dans ta boucle. L’erreur Allocation overflow, c’est tout simplement le tableau qui déborde.
a? signifie bien a|{rien}.est ce que a? veut dire a|{rien} ou bien veut dire a|{tout sauf a} c'est à dire en termes de motif a|[^a]
Le motif a|[^a], quant à lui, revient à dire « accepte tout ce qui est un truc ou tout ce qui n’est pas un truc », autrement dit : absolument tout ce qui existe. C’est comme l’astuce parfois utilisée [/s/S] (tout ce qui est un espacement ou tout ce qui n’est pas un espacement) quand le . ne suffit pas(1), car . ne reconnaît pas les retours chariot "\r" ni les sauts de lignes "\n".
Le problème c’est cette fichue chaîne vide "" qui se trouve n’importe où dans toute chaîne. Dans mon précédent post, j’ai dit que dans "xy" il y avait une chaîne vide entre "x" et "y". En fait, c’est encore pire que ça : il y en a une infinité. Et il y en a aussi en début et en fin de chaîne.A mon avis le curseur ne fait jamais du surplace car soit il avance lorsque un match est trouvé et dans ce cas result != null et la boucle continue, soit il est remis à 0 si aucun match n'est trouvé et dan ce cas result = null et la boucle s'achève. Tout ça demande peut être un peu plus d'éclaircissement. Le débat est donc toujours ouvert.
Merci pour toute participation.
Le curseur peut bel et bien faire du surplace, il existe même plusieurs éléments de regexp prévus pour ça :
- les ancres ^ et $ ;
- la limite de mot (word boundary) \b, qui correspond exactement à une position entre \w et \W, et réciproquement(2) ;
- le contraire du précédent, \B, la « non limite de mot » ;
- les, euh… « groupes de longueur 0 », par exemple (?=abc) : ça reconnaît la séquence "abc", mais ça ne fait pas avancer le curseur.
Ce sont donc des correspondances de longueur nulle. En langage savant, on appelle ça des assertions. L’exemple le plus parlant est sans doute celui-ci :
Dans le cas qui nous intéresse, l’alternative {rien} qui est cachée dans le motif a? est une correspondance de longueur nulle. Pour vérifier, essaye simplement /a?/.test("b").
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 let str = ""; let reg = /^/g; for (let i = 0; i < 7; i++) { console.log(reg.lastIndex); // toujours 0 console.log(reg.exec(str)); // toujours "" }
Et sinon, tu as essayé a+b ?
(1) Ça marche aussi avec [\w\W] et [\d\D].
(2) \b est un peu erronée car elle ne comprend pas les caractères accentués, entre autres. Par exemple dans "réponse", pour elle, il y a une transition entre "r" et "é".
La FAQ JavaScript – Les cours JavaScript
Touche F12 = la console → l’outil indispensable pour développer en JavaScript !
Partager