9
votes

Comportement de Regexp JavaScript inattendu

Je crée un objet RegExp (en JavaScript) pour tester la présence d'un certain nombre:

console.log( test.test( '1' ) ); // true
console.log( test.test( '0' ) ); // false - why?
console.log( test.test( '1' ) ); // true
console.log( test.test( '2' ) ); // false - why?
console.log( test.test( '2' ) ); // true - correct, but why is this one true?


0 commentaires

3 Réponses :


6
votes

Supprimez le drapeau 'g' . Lorsque vous utilisez le drapeau 'g ', il met à jour la propriété lastIndex de la REGEX (préparation de la recherche successive sur la même chaîne), puis commence la recherche suivante à partir de celle-ci. valeur d'index (vous donnant ainsi une fausse lecture sur votre prochaine recherche).

question similaire et réponse ici: Pourquoi regex JavaScript // g Drapeau affectant l'état?


3 commentaires

Voulez-vous dire qu'il ignore la chaîne d'entrée la deuxième fois que je l'appelle et continue de rechercher des correspondances dans la chaîne donnée précédemment? C'est assez bizarre


@ Dave. Il est la mise à jour lastIndex dans l'objet regex et à partir du deuxième match à partir de là que vous donne la fausse lecture.


Ah Ok, je pense que je comprends maintenant. J'ai mis un test rapide ensemble et il semble qu'il utilise la nouvelle chaîne, mais des recherches à partir du dernier index correspondant: Jsfiddle.net/ SNXSG Cela doit être le comportement le plus étrange jamais, mais au moins je comprends maintenant. Merci!



7
votes

par documentation: https://developer.mozilla.org/ EN-US / DOCS / JavaScript / Référence / Global_Objects / Regexp / Test # Description

test appelé plusieurs fois sur la même instance d'expression régulière globale passeront après la correspondance précédente.

Vous pouvez confirmer ce comportement: xxx

Il n'a pas de sens d'utiliser le drapeau g si tout ce que vous voulez est de confirmer une seule correspondance contre diverses chaînes.


1 commentaires

Merci. Vous étiez quelques minutes derrière jfriend00 mais cela semble être une réponse plus complète. Juste en attendant le compte à rebours expirer à accepter!



1
votes

Selon MDN ,

comme avec exec code> (ou en combinaison avec elle), test code> appelé plusieurs fois sur la même instance d'expression régulière globale passeront après la match précédent. p> blockQuote>

techniquement, la spécification ECMAScript 5.1 dit P>

15.10.6.3 Regexp .pototype.test (string) strong> p>

Les étapes suivantes sont prises: p>

  1. Laissez le match Soyez le résultat de l'évaluation de l'algorithme code> regexp.pototype.exec code> (15.10.6.2) sur cet objet REGEXP en utilisant string em> comme le argument. li>
  2. si match em> n'est pas null, puis retournez vrai code>; sinon retourner faux code>. li> ol>

    15.10.6.2 Regexp .pototype.exec (chaîne) forte> p>

    Effectue une correspondance d'expression régulière de string em> contre le régulier expression et retourne un objet de tableau contenant les résultats de la Correspondre, ou null code> si string em> ne correspond pas. p>

    La chaîne tostring ( chaîne em>) est recherchée par une occurrence de la Modèle d'expression régulier comme suit: p>

    1. Laissez r em> être cet objet Regexp. li>
    2. [...] li>
    3. [...] li>
    4. laisse lanceIndex em> résulte de l'appelant la méthode interne [[get]] de r em> avec argument " lastIndex code>". LI >
    5. laisse i em> la valeur de TOINTEGER ( LastDex em>). Li>
    6. laissez global em> résulte de l'appelant la méthode interne [[get]] de r em> avec argument " global code>". li >
    7. Si global em> est faux code>, puis laisse i em> = 0. li>
    8. [...] li>
    9. [...] li>
    10. laissez e em> être r em> 's endindex em> valeur. li>
    11. si global em> est vrai code>,
      1. appelez la méthode interne [[Mettre]] de r em> avec des arguments " lastIndex code>", e em> et vrai code>. li> ol> li>
      2. [...] li> ol> blockQuote>

        Par conséquent, pour éviter ce comportement, vous pouvez p>

        • Évitez d'utiliser un drapeau global g code> p>

          De cette façon, à l'étape 7, i code> sera 0 code> au lieu de lastIndex code>. p> li>

        • réinitialiser lastIndex code > manuellement après chaque utilisation p>

          La valeur de la propriété lastIndex code> Spécifie la position de la chaîne à qui pour commencer la prochaine correspondance. P> blockQuote>

          Par exemple, P>

          var test = /[0-9]/g;
          test.test('0');        // true
          test.lastIndex;        // 1
          '0'.search(test) > -1; // true
          test.lastIndex;        // 1 (unaltered)
          !!'0'.match(test);     // true
          test.lastIndex;        // 0
          
        • Utilisez correspondant code> ou Recherche code> Méthodes de chaîne p>

          correspondez code> réticents lastIndex code> à 0 et recherche code> l'ignore: p>

          15.5.4.10 chaîne .pototype.Match (regexp) strong> p>

          [...] [si] global em> est vrai code>, appelez la méthode interne [[Mettre]] de rx em> avec des arguments " lastIndex code> "et 0. [...] p>

          15.5.4.12 String .pototype.Search (regexp) strong> p>

          [...] Rechercher la valeur string em> à partir de son début pour une occurrence de la Modèle d'expression régulier rx em>. [...] le lastIndex code> et global code> Les propriétés de Regexp em> sont ignorées lors de la recherche. [...] p> blockQuote>

          Par exemple, P>

          var test = /[0-9]/g;
          test.test('0');      // true
          test.lastIndex;      // 1
          test.lastIndex = 0;
          test.test('1');      // true
          


0 commentaires