У меня есть странная проблема с проверкой, которую я пишу на форме. Это кнопка "Проверить имя пользователя" рядом с входом. Значение по умолчанию ввода - это имя пользователя, например "betamax". Когда я нажимаю "Проверить имя пользователя", он передает регулярное выражение и отправляет имя пользователя на сервер. Сервер ведет себя так, как ожидалось, и возвращает "2", чтобы сообщить javascript, что они представляют свое собственное имя пользователя.
Затем, когда я снова нажимаю кнопку, regex терпит неудачу. На сервер ничего не отправляется, потому что регулярное выражение не сработало. Если я снова нажму кнопку, регулярное выражение пройдет, а затем имя пользователя будет отправлено на сервер.
Я буквально не могу понять, что бы это сделало! Мне это не имеет смысла!
Изменить: я протестировал проблему в 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>
/^[^-_]([a-z0-9-_]{4,20})[^-_]$/gi;
Вы используете g
(глобальный) RegExp
. В JavaScript глобальное regexen имеет состояние: вы вызываете их (с exec
, test
и т.д.) В первый раз, вы получаете первое совпадение в заданной строке. Вызовите их снова, и вы получите следующий матч и так далее, пока не получите совпадение, и он сбрасывается до начала следующей строки. Вы также можете записать regex.lastIndex= 0
в reset это состояние.
(Это, конечно, абсолютно ужасный дизайн, который может смутить и вызвать странные ошибки. Добро пожаловать в JavaScript!)
Вы можете опустить g
из RegExp
, так как вы проверяете только одно соответствие.
Кроме того, я не думаю, что вы хотите [^-_]
спереди и сзади. Это позволит любому персонажу на каждом конце, т.е. *plop!
будет действительным. Вероятно, вы думаете о утверждениях lookahead/lookbehind, но они недоступны в JavaScript. (Ну, взгляд должен быть, но он сломан в IE.) Вместо этого предложите:
/^[a-z0-9][a-z0-9_-]{2,18}[a-z0-9]$/i
[a-z0-9-_]
Это неправильно, последний -
должен быть в начале или конце.
[a-z0-9_-]
Не может ли это вызвать эту проблему или нет, я не знаю.
Дополнительные примечания:
Первый и последний символы могут быть любыми символами, которые не являются -
или _
, а не ограничиваются a-z0-9
a-z0-9
не включает символы верхнего регистра. Для этого вам нужно a-zA-Z0-9
.
a-zA-Z0-9_
можно сократить до \w
в большинстве двигателей RegEx. Я не пробовал это в JavaScript.
-
это специальный символ в группах ... как вы можете видеть, так как вы используете его для az
. Из-за этого он определяется как являющийся только литералом -
как первый или последний символ RegEx. Сказав это, вам может потребоваться переключить его также в [^-_]
(на [^_-]
).
test
для этого, это своего рода безумный запрос - какую группу захвата вы пытаетесь протестировать? Чтобы не оправдывать JavaScript, они выбрали самое безумное из возможных решений слегка сумасшедшей проблемы.