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.
Ok, je ne savais pas pour la r�cursivit� de la fonction dans une boucle while...
Alors je crois avoir compris, �a vient du fait que tu rajoutes var au sein de la boucle, c'est aussi pour ce genre de raison que j'avais externalis� le "var".
"var" r�initialise ta recherche � chaque it�ration, je pense, donc l'allocation overflow serait bien due au remplissage du tableau.
Sinon je crois que le point d'interrogation ne sert � rien si tu le mets au d�but, puisqu'il signifie oui ou non pour le dernier caract�re ou la derni�re classe, mais je peux me tromper sur ce point aussi.
Donc le code corrig� serait :
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 function test() { try { var regEx = /a|ab/g; var str = "aaab"; if(!regEx.test(str)) return null; var a = new Array(); var result; while((result = regEx.exec(str)) != null) { a.push(result.index); } return a; } catch(exp) { alert(exp.message); } }
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 !
J'ai fait un test qui confirme que le curseur fait du surplace avec la regexp /a?|ab/g;
voici le test et la capture de la sortie de console :
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; while((result = regEx.exec(str)) != null) { console.log(result.index); a.push(result.index); } return a; } catch(exp) { alert(exp.message); } } test();
m�me avec la regexp /ab|a?/g �a bloque en position 4
pour moi l'allocation overflow vient bien d'un remplissage de tableau sans fin, lui m�me du au pointeur de l'expression qui reste le m�me, d'o� le risque d'utiliser des expressions de longueur potentielle 0 sans rien de plus.
C'est pourtant bien ce qui se passe, mais ce comportement est propre aux m�thodes RegExp.prototype.test et RegExp.prototype.exec qui d�terminent la position suivante � partir de la derni�re position et de la longueur de la correspondance.Envoy� par abdou_moujar
En r�sum�: position suivante = derni�re position + 0 = derni�re position. Donc �a ne bouge plus.
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8 > re = /./g /./g > re.test('ab') true > re.test('ab') true > re.test('ab') falsePar contre, les m�thodes String.prototype.match, String.prototype.replace et String.prototype.split elles, avancent automatiquement d'une position lorsque la correspondance est vide. Formuler autrement, ces m�thodes ne testent jamais deux fois la m�me position.
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11 > re = /z?/g /z?/g > re.test('ab') true > re.test('ab') true > re.test('ab') true > re.test('ab') true ...(Il n'y a pas eu cr�ation d'une cha�ne infinie de # allant jusqu'� l'overflow. Le pointeur avance.)
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2 > 'abc'.replace(/z?/g, '#') '#a#b#c#'
C'est loin d'�tre une ineptie car � la base, les moteurs de regex suivant le standard POSIX renvoient non pas la premi�re alternative qui r�ussit mais celle dont la correspondance est la plus longue, et ce n'est que lorsqu'il y a "�galit�" que l'ordre est pris en compte. C'est le comportement auquel il faut s'attendre avec des outils comme grep, sed, awk, avec MySQL ou les fonctions d�pr�ci�es ereg* de PHP. Par contre, en Javascript, PHP (preg_*), Ruby, Perl, Python, Java, .net... , la premi�re alternative qui r�ussit est retenue quelque soit la longueur de la correspondance.Envoy� par Watilin
Merci pour toutes vos collaborations
C'est vrai l'indexe renvoy� par la m�thode regEx.exec(str) peut faire du surplace. Je l'ai v�rifi� sur le fameux motif /a?/g appliqu� � la chaine "aaab" en utilisant une nested function ex�cut�e de mani�re r�p�titive au lieu d''une boucle while, voici le code :
En ex�cutant la fonction test() j'obtient la sortie suivante :
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 function test() { var str = "aaab", re = /a?/g; var ti = new Date(), tmax = 5000, dt = 1000; var i = 1; start(); function start() { var r = re.exec(str); if(r != null) console.log("N° " + i + " : Index = " + r.index + " Match = " + RegExp.lastMatch); i++; var t = new Date(); if((t - ti) <= tmax) setTimeout(start, dt); } }
N� 1 : Index = 0 Match = a
N� 2 : Index = 1 Match = a
N� 3 : Index = 2 Match = a
N� 3 : Index = 3 Match =
N� 4 : Index = 3 Match =
N� 5 : Index = 3 Match =
N� 6 : Index = 3 Match =
On voit bien que le curseur bloque sur l'indexe 3 (la lettre b) et le match renvoie toujours la m�me chaine vide(le fameux a|{rien}) et la variable r n'est jamais nulle.
C'est ce qui explique l'exception Allocation overflow � cause du tableau qui n'en finit jamais de se remplir.
Tout autre �claircissement serait le bien venu. Merci
Une info compl�mentaire : la taille maximale d�un tableau, fix�e par la sp�cification ECMAScript, est de 232 - 1. Si on essaye de d�passer cette limite�
� On obtient le message d�erreur suivant :
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2 arr = new Array(2**32 - 1) arr.push("oups")
C�est un message diff�rent de Allocation overflow. �a signifie que la limite de m�moire du navigateur (limite physique) est atteinte avant la limite de taille du tableau (limite virtuelle).
Code : S�lectionner tout - Visualiser dans une fen�tre � part RangeError: invalid array length
La FAQ JavaScript � Les cours JavaScript
Touche F12 = la console → l�outil indispensable pour d�velopper en JavaScript !
Enfin ce qui m'�tonne la dedans, c'est qu'un tableau rempli x fois avec de petits entiers fasse d�border la m�moire du navigateur, mais je peux me tromper ! C'est sans doute oublier que javascript n'a qu'un type "number"...
C'est pourquoi je pensais � la limite du tableau proprement dit, sous chrome...
Sinon sur un appel r�current de fonction infini, la limite atteinte lance le message "Maximum call stack size exceeded" sous Chrome
Apr�s depuis Quantum, j'ai une pr�f�rence nette pour Firefox qui est redevenu le navigateur optimis� que j'aimais...![]()
En effet, le type Number est repr�sent� par les flottants double pr�cision de la norme IEEE-754. Ils tiennent sur 64 bits, soit 4 octets.
Mais m�me en supposant que les nombres n�occupent qu�un seul octet, remplir un tableau de 232 entr�es demanderait un total de 4 Go de m�moire vive. Je ne crois pas qu�il existe un navigateur aujourd�hui qui peut allouer autant � son moteur JavaScript.
Quant � la limite de r�cursion, on ne la voit pas dans le cas pr�sent car on utilise une boucle while, donc il n�y a pas d�empilement d�appels de fonction.
La FAQ JavaScript � Les cours JavaScript
Touche F12 = la console → l�outil indispensable pour d�velopper en JavaScript !
Partager