Регулярное выражение Javascript, возвращающее true.. затем false.. затем true.. и т. Д.

У меня странная проблема с проверкой, которую я пишу в форме. Это кнопка "Проверить имя пользователя" рядом со входом. В качестве входного значения по умолчанию используется имя пользователя, например, "betamax". Когда я нажимаю "Проверить имя пользователя", он передает регулярное выражение и отправляет имя пользователя на сервер. Сервер ведет себя как ожидалось и возвращает "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>

2 ответа

Решение
/^[^-_]([a-z0-9-_]{4,20})[^-_]$/gi;

Вы используете g (Глобальный) RegExp, В JavaScript глобальные регулярные выражения имеют состояние: вы вызываете их (с exec, test и т.д.) в первый раз вы получите первое совпадение в данной строке. Вызовите их снова, и вы получите следующее совпадение, и так далее, пока не получите совпадение, и оно сбрасывается в начало следующей строки. Вы также можете написать regex.lastIndex= 0 сбросить это состояние.

(Это, конечно, абсолютно ужасный элемент дизайна, который может запутать и вызвать странные ошибки. Добро пожаловать в JavaScript!)

Вы можете опустить g от твоего RegExp, так как вы тестируете только один матч.

Кроме того, я не думаю, что вы хотите [^-_] спереди и сзади. Это позволит любой символ на каждом конце, т.е. *plop! будет действительным. Вы, вероятно, думаете об утверждениях типа "взгляд в будущее", но они не доступны в 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.

Другие вопросы по тегам