Javascript regex 返回 true. . then false. . then true. . etc

我在表单上写的验证有一个奇怪的问题。它是一个“检查用户名”按钮旁边的输入。输入默认值是用户名,例如“ betamax”。当我按‘ CheckUsername’时,它会传递正则表达式并将用户名发送到服务器。服务器的行为符合预期,并返回’2’来告诉 javascript 他们正在提交自己的用户名。

然后,当我再次单击该按钮时,正则表达式失败。显然没有向服务器发送任何内容,因为正则表达式失败了。如果我再次按下按钮,正则表达式将通过,然后用户名将发送到服务器。

我真的不知道是什么让它这样做的! 这对我来说毫无意义!

编辑: 我已经在 Firefox 和 Chrome (mac)中测试了这个问题

这是我的暗号:

$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;


}

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>
29207 次浏览
[a-z0-9-_]

这是错误的,最后的 -必须在开始或结束。

[a-z0-9_-]

这是否会导致这个问题,我不知道。

附加说明:

第一个和最后一个字符允许是任何不是 -_的字符,而不是仅限于 a-z0-9

a-z0-9不包括大写字母。这需要 a-zA-Z0-9。 在大多数正则表达式引擎中,a-zA-Z0-9_可以缩短为 \w,我还没有在 JavaScript 中尝试过。

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

您正在使用 g(全局) RegExp。在 JavaScript 中,全局正则表达式具有状态: 第一次调用它们(使用 exectest等) ,就会得到给定字符串中的第一个匹配项。再次调用它们,就会得到下一个匹配项,以此类推,直到没有匹配项,并且它重置为下一个字符串的开始。您还可以编写 regex.lastIndex= 0来重置此状态。

(这当然是一个非常糟糕的设计,肯定会引起混淆和奇怪的错误。欢迎使用 JavaScript!)

您可以从 RegExp中省略 g,因为您只测试一个匹配项。

另外,我认为你不想 [^-_]在前面和后面。这将允许 任何字符在每个结束,即。*plop!是有效的。您可能会考虑前瞻/后顾断言,但是 JavaScript 中没有这种断言。(好吧,向前看应该是,但它在 IE 中被破坏了。)建议改为:

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