JeuWeb - Crée ton jeu par navigateur
Reg Exp javascript (si si....) - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Reg Exp javascript (si si....) (/showthread.php?tid=7260)



Reg Exp javascript (si si....) - Wells - 25-11-2014

On en est la, hé oui, meme aprés 10 ans.

J'ai un code qui me rend dingue. Je suis sur que la solution est devant moi mais non :

Code :
<script>
var reg=/[0-9]+/g;

if(!reg.test('2')) document.write('<br /><font style="color:red;">2</font>');
else document.write('<br /><font style="color:green;">2</font>');
if(!reg.test('22')) document.write('<br /><font style="color:red;">22</font>');
else document.write('<br /><font style="color:green;">22</font>');
if(!reg.test('2.')) document.write('<br /><font style="color:red;">2.</font>');
else document.write('<br /><font style="color:green;">2.</font>');
if(!reg.test('2.1')) document.write('<br /><font style="color:red;">2.1</font>');
else document.write('<br /><font style="color:green;">2.1</font>');
if(!reg.test('2.12')) document.write('<br /><font style="color:red;">2.12</font>');
else document.write('<br /><font style="color:green;">2.12</font>');
if(!reg.test('22.1')) document.write('<br /><font style="color:red;">22.1</font>');
else document.write('<br /><font style="color:green;">22.1</font>');
if(!reg.test('22.22')) document.write('<br /><font style="color:red;">22.22</font>');
else document.write('<br /><font style="color:green;">22.22</font>');

</script>

Pourquoi certains passent et pas d'autre. Normalement seul les deux premiers devraient être valide)


RE: Reg Exp javascript (si si....) - Patatruc - 25-11-2014

Hello,

Essaie ça, pour indiquer que le test porte sur la totalité de la chaîne (sans l'option /g) :

Code :
var reg=/^[0-9]+$/;

Ou alors var reg=/^\d+$/;

(25-11-2014, 06:56 PM)Wells a écrit : On en est la, hé oui, meme aprés 10 ans.

J'ai un code qui me rend dingue. Je suis sur que la solution est devant moi mais non :

Code :
<script>
var reg=/[0-9]+/g;

if(!reg.test('2')) document.write('<br /><font style="color:red;">2</font>');
else document.write('<br /><font style="color:green;">2</font>');
if(!reg.test('22')) document.write('<br /><font style="color:red;">22</font>');
else document.write('<br /><font style="color:green;">22</font>');
if(!reg.test('2.')) document.write('<br /><font style="color:red;">2.</font>');
else document.write('<br /><font style="color:green;">2.</font>');
if(!reg.test('2.1')) document.write('<br /><font style="color:red;">2.1</font>');
else document.write('<br /><font style="color:green;">2.1</font>');
if(!reg.test('2.12')) document.write('<br /><font style="color:red;">2.12</font>');
else document.write('<br /><font style="color:green;">2.12</font>');
if(!reg.test('22.1')) document.write('<br /><font style="color:red;">22.1</font>');
else document.write('<br /><font style="color:green;">22.1</font>');
if(!reg.test('22.22')) document.write('<br /><font style="color:red;">22.22</font>');
else document.write('<br /><font style="color:green;">22.22</font>');

</script>

Pourquoi certains passent et pas d'autre. Normalement seul les deux premiers devraient être valide)



RE: Reg Exp javascript (si si....) - Xenos - 25-11-2014

Effectivement, le résultat m'a laissé dubitatif, mais après recherche, il s'explique parfaitement.
Partons du code plus léger suivant:


var reg=/[0-9]+/g;
var tests = ['2', '22', '2', '2.1', '2.12', '22.1', '22.22', 'abc4e', '.4.', 'd4.', '.x4', '.4x'];
for (k=0,s=tests.length;k<s;++k)
{
console.log(reg.lastIndex, ' # ', tests[k]);
document.write('<br /><font style="color:'+ (reg.test(tests[k])? 'green': 'red') +';">'+tests[k]+'</font>');
//document.write("<br/>[color="+ (reg.test(tests[k])? 'green': 'red') +']'+tests[k]+'[/color]');
}

Résultat a écrit :2
22
2.
2.1
2.12
22.1
22.22
abc4e
.4.
d4.
.x4
.4x

Si on teste la même chose sans le modificateur "g", alors toutes les chaînes sont matchées: en effet, toutes contiennent une décimale quelque part et [0-9]+ est une regex validée si on trouve un ou plusieurs caractères consécutifs entre 0 et 9 (donc, un ou plusieurs chiffres à la suite).


Pourquoi le drapeau g (global match) invalide-t-il les chaines "2. 22.1 .4. .4x"?

Ce drapeau permet de faire "boucler" le test d'une regex, en partant de la position de la dernière occurrence trouvée précédemment.

En d'autres mots, si g est utilisé, la chaîne ne sera testée qu'à partir de la position "lastIndex". Cette position, initialement à 0 quand on crée l'objet RegExp, contient la position de fin de la dernière occurrence valide trouvée dans la dernière chaîne testée.
Source: StackOverflow

Ainsi:
• On crée l'objet reg (lastIndex=0)
• On teste la première chaîne '2', à partir de lastIndex (0): on trouve une correspondance ("2"), et lastIndex=1
• On teste la chaîne suivante '22', à partir de lastIndex (1): on trouve une correspondance ("2" le second chiffre), et lastIndex=2
• On teste la chaîne suivante '2', à partir de lastIndex (2): on ne trouve rien (lastIndex dépasse la longueur de la chaine), donc la regex ne match pas cette chaîne. Comme il n'y a pas d'occurrence trouvée dans cette chaîne, lastIndex=0
• On teste la chaîne suivante '2.1', à partir de lastIndex (0): on trouve une première correspondance ("2"), puis une seconde ("1") d'où lastIndex=3 (la position après ce "1" trouvé)
• On teste la chaîne suivante '2.12', à partir de lastIndex (3): on trouve une correspondance ("2") donc lastIndex=4
• On teste la chaîne suivante '22.1', à partir de lastIndex (4): on ne trouve (la position 4 est après le "1", en fin de chaine) donc lastIndex=0
etc
D'où les chaînes non matchées.
La solution du problème peut passer ou bien par l'abandon du modificateur g s'il n'est pas nécessaire (à toi de savoir s'il l'est en fonction de tes besoins) ou bien par la réinitialisation manuelle de la valeur lastIndex en insérant reg.lastIndex = 0; avant le test reg.test().