Caro_deb
Caro_deb

Reputation: 279

Issue with username regex validation

I searched SO before posting, but couldn't find an answer that would work for me.

Below is a simple JS script to test a username.

The username length validation work fine BUT the character validation doesn't:

All non-allowed characters (such as $%;[+)) pass whereas they should return an error.

<script type="text/javascript">
 $(document).ready(function() {
    $("#username").change(function() {
        var username = $("#username").val();
        var msgbox = $("#status");
        var usernameRegex = /^[a-zA-Z0-9][a-zA-Z0-9\._-]$i/

         if ((username.length >= 4 && username.length <= 20) &&  
 (usernameRegex.test(username.value) == false)) {

            $.ajax({
                type: "POST",
                url: "username.php",
                data: "username=" + username,
                success: function(msg) {

                    if (msg == 'OK') {

                        msgbox.html('<img src="ok.png">');

                    } else {
                        msgbox.html(msg);
                    }
                }
             });
        } else {

            $("#status").html('<img src="no.png">Try again');
        }
     });
});
</script>

What am I missing?

Upvotes: 0

Views: 861

Answers (3)

theftprevention
theftprevention

Reputation: 5213

There's a problem with your regular expression, and it's not just the $i/. You have:

var usernameRegex = /^[a-zA-Z0-9][a-zA-Z0-9\._-]$i/;

That second token, [a-zA-Z0-9\._-], is only evaluated once. It checks the first character for the first token, then the second character for the second token, and then expects the end of the string because of $. Even after changing your test condition to true and fixing the rest of the logic, your original regular expression will fail all usernames above two characters.

Try this instead:

var usernameRegex = /^[a-zA-Z0-9][a-zA-Z0-9\._-]+$/i;

The + ensures that the regex will look for at least one character in the token, and match them until the string ends.

Finally, as others have mentioned, you need usernameRegex.test(username) instead of usernameRegex.test(username.value), and it needs to test for a true value, not false.

See a working demo here.

Upvotes: 1

Ibrahim Najjar
Ibrahim Najjar

Reputation: 19423

/^[a-zA-Z0-9][a-zA-Z0-9\._-]{4,20}$i/
                                  ^^
                        Here is the problem

You probably wanted to specify the case-insensitive flag but by accident you put i inside the regular expression pattern itself, you need to modify your expression to this:

/^[a-zA-Z0-9][a-zA-Z0-9\._-]{4,20}$/i

and as they guys have pointed out you should test for a true condition or in other words, you need to check if the string actually matches the pattern and thus contains only the characters you allow.

Upvotes: 1

Schleis
Schleis

Reputation: 43700

You are examining the results of your test backwards. The test() method returns true if the pattern matches. And you are checking for a false value.

Change it to:

if ((username.length >= 4 && username.length <= 20) 
    &&  usernameRegex.test(username.value)) {

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FRegExp%2Ftest

Upvotes: 1

Related Questions