2010-04-13 9 views
69

J'ai un problème étrange avec la validation que j'écris sur un formulaire. C'est un bouton 'Check Username' à côté d'une entrée. La valeur par défaut d'entrée est le nom d'utilisateur par exemple 'betamax'. Lorsque j'appuie sur 'Check Username', il passe la regex et envoie le nom d'utilisateur au serveur. Le serveur se comporte comme prévu et renvoie '2' pour indiquer au javascript qu'il soumet son propre nom d'utilisateur.Javascript regex renvoyant true .. then false .. then true .. etc

Ensuite, lorsque je clique à nouveau sur le bouton, l'expression régulière échoue. Rien n'est envoyé au serveur évidemment parce que l'expression régulière a échoué. Si j'appuie à nouveau sur le bouton, la regex passe et le nom d'utilisateur est envoyé au serveur.

Je ne peux littéralement pas comprendre ce que cela ferait de le faire! Ça n'a aucun sens!

Edit: Je l'ai testé le problème dans Firefox et Chrome (Mac)

Ceci est mon code:

$j("#username-search").click(checkUserName); 

function checkUserName() { 
    var userName = $j("#username").val(); 


    var invalidUserMsg = 'Invalid username (a-zA-Z0-9 _ - and not - or _ at beginning or end of string)'; 
    var filter = /^[^-_]([a-z0-9-_]{4,20})[^-_]$/gi; 
    if (filter.test(userName)) { 
     console.log("Pass") 
     $j.post(
     "/account/profile/username_check/", 
     { q: userName }, 
     function(data){ 
      if(data == 0) { 
       $j("#username-search-results").html("Error searching for username. Try again?"); 
      } 
      else if(data == 5) { 
       $j("#username-search-results").html(invalidUserMsg); 
      } 
      else if(data == 4) { 
       $j("#username-search-results").html("Username too short or too long."); 
      } 
      else if(data == 2) { 
       $j("#username-search-results").html("This is already your username."); 
      } 
      else if(data == 3) { 
       $j("#username-search-results").html("This username is taken."); 
      } 
      else if(data == 1){ 
       $j("#username-search-results").html("This username is available!"); 
      } 
     }); 
    } else { 
     console.log("fail") 
     $j("#username-search-results").html(invalidUserMsg); 
    } 

    return false; 

} 

Le code HTML:

<input name="username" id="username" value="{{ user.username }}" /> 
<input type="button" value="Is it taken?" id="username-search"> 
<span id="username-search-results"></span> 

Répondre

130
/^[^-_]([a-z0-9-_]{4,20})[^-_]$/gi; 

Vous utilisez un g (global) RegExp. En JavaScript, regexen global a l'état: vous les appelez (avec exec, test etc.) la première fois, vous obtenez la première correspondance dans une chaîne donnée. Appelez-les à nouveau et vous obtiendrez le match suivant, et ainsi de suite jusqu'à ce que vous n'obteniez aucune correspondance et qu'il se réinitialise au début de la chaîne suivante. Vous pouvez également écrire regex.lastIndex= 0 pour réinitialiser cet état.

(Ceci est bien sûr une pièce absolument terrible de la conception, garantie à semer la confusion et provoquer des erreurs étranges. Bienvenue sur JavaScript!)

Vous pouvez omettre le g de votre RegExp, puisque vous testez seulement pour une rencontre.

Aussi, je ne pense pas que vous voulez [^-_] à l'avant et à l'arrière. Cela permettra un caractère à chaque extrémité, à savoir. *plop! serait valide. Vous pensez probablement à des assertions lookahead/lookbehind, mais elles ne sont pas disponibles en JavaScript. (Eh bien, lookahead est censé être, mais il est cassé dans IE.Suggérer à la place:

/^[a-z0-9][a-z0-9_-]{2,18}[a-z0-9]$/i 
+5

J'ai appris quelque chose de nouveau aujourd'hui! Je n'ai jamais traité avec RegEx dans JS avant. :) – Powerlord

+3

C'est ça. Je comprends normalement/par habitude, mais je suppose que je ne le ferai plus! Merci! – betamax

+0

+1 Je voudrais dire que c'est uniquement pour l'utilisation du mot "regexen", mais c'est une bonne réponse dans tous les aspects ;-) –

2
[a-z0-9-_] 

C'est faux, le dernier - doit être au début ou à la fin.

[a-z0-9_-] 

Si cela causerait ce problème ou non, je ne sais pas.

Notes complémentaires:

Les premiers et derniers caractères sont autorisés à être un caractère non - ou _ plutôt que d'être limité à a-z0-9

a-z0-9 ne comprend pas les caractères majuscules. Vous avez besoin de a-zA-Z0-9 pour cela. a-zA-Z0-9_ peut être raccourci à \w dans la plupart des moteurs RegEx. Je ne l'ai pas essayé en JavaScript.

+0

Merci pour le conseil. Pourquoi exactement l'ordre est-il important? Malheureusement, cela n'a pas résolu le problème que je vois. Je viens de le tester en chrome (utilisait Firefox) et il fait la même chose. – betamax

+0

'-' est un caractère spécial dans les groupes ... comme vous pouvez le voir, puisque vous l'utilisez pour' a-z'. Pour cette raison, il est défini comme étant seulement un '-' littéral comme le premier ou le dernier caractère d'un RegEx. Cela dit, il se peut que vous deviez également l'activer dans [^ -_] '(à' [_ _-] '). – Powerlord

+0

Oups, je viens de remarquer que j'ai mis '/ w' au lieu de' \ w' dans ma réponse. Devrait être réparé maintenant. – Powerlord

Questions connexes