Validate password fields using Javascript / Regex

Asked

Viewed 911 times

1

I’m setting up a page where the user can change his password and need to validate two input’s with the following rules:

  1. the password must have 1 character and 1 number.
  2. there cannot be 2 characters or repeated numbers (Ex: "aa", "11")

I was able to solve item 1 with Regex, but I’m not able to solve item 2.


    validador: function(){
     //this.form.senha && this.form.senha são os locais dos inputs

        if (this.form.senha_confirmacao != this.form.senha) {
            alert('As duas senhas estão divergentes')
            return false;
        } else {

            let senha = this.form.senha_confirmacao;
            let regex = /^(?=(?:.*?[A-Z]){0})(?=(?:.*?[0-9]){1})(?=(?:.*?[!@#$%*()_+^&}{:;?.]){0})(?!.*\s)[0-9a-zA-Z!@#$%;*(){}_+^&]*$/; 

            if(senha.length < 6){                
                Notify.create({message: "A senha deve conter no minímo 6 digitos!"});            
                return false;

                } else if(!regex.exec(senha)){                    
                    Notify.create({message: "A senha deve conter no mínimo 1 número e 1 letra"});            
                    return false;

                }   
                    return true;  


    }
  }

1 answer

2


Your regex is a bit confused. For example, the quantifier {0}, which means "zero occurrences". That is, you defined an excerpt that does not occur (or that "occurs zero times", which is the same as "not existing") and so it is ignored. So much so that the stretch (?:.*?[A-Z]){0} is not forcing to have letters, see.

There is also the use of {1}, which means "an incident". But by default, anything you put in a regex already means that it will occur once, so it is redundant and can be removed ((alguma coisa){1} is the same as (alguma coisa)).

So to check if the password must have a letter and a number, just change the lookaheads for (?=.*[a-zA-Z]) and (?=.*[0-9]) (notice that I used [a-zA-Z], for [A-Z] only take uppercase letters).

From what I understand you also want to check the presence of at least one of the special characters ([!@#$%*()_+^&}{:;?.]), since you have a Lookahead for them, then just take the {0} his as well.

And if you want to validate the string size, you can do it in regex itself: instead of using * (zero or more occurrences), you can use {6,} (at least 6 occurrences, no maximum limit). If you also want to limit the maximum value, you can use something like {6,20} (minimum 6, maximum 20 occurrences).

The excerpt (?!.*\s) also seems unnecessary: it checks if there are no spaces, TAB’s or line breaks (which is what the shortcut \s means), but as the rest of regex is already very restrictive on this, this verification is redundant and can also be removed.


To check that the same character repeats at consecutive positions, you can use parentheses to create a capture group and then use backreferences to refer to this group. The basic idea is to do something like this:

(caractere)(?!\1)

The parentheses capture the character, and \1 contains the character that was captured. The Negative Lookahead (?!\1) checks whether this character nay occurs shortly after. That is, it checks if the same character does not occur twice consecutively (in this case, the "character" is the stretch you want to check: [0-9a-zA-Z!@#$%;*(){}_+^&]). Then just repeat this structure over and over again:

(?:(caractere)(?!\1)){6,}

So I have a character that doesn’t appear twice in a row, and it happens at least 6 times. The full expression is:

function valida(senha) {
    let regex = /^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[!@#$%*()_+^&}{:;?.])(?:([0-9a-zA-Z!@#$%;*(){}_+^&])(?!\1)){6,}$/;
    if (regex.test(senha)) {
        console.log(senha, '= válida');
    } else {
        console.log(senha, '= inválida');
    }
}

['a@1', 'abc@123', 'aab@123'].forEach(s => valida(s));

See here the regex working.


regex above considers that special characters cannot be repeated either (if @@, the string is invalid). But if you want to prevent only letters and numbers from repeating, just switch to:

/^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[!@#$%*()_+^&}{:;?.])(?:([0-9a-zA-Z])(?!\1)|[!@#$%;*(){}_+^&]){6,}$/

Now the regex uses alternation (the character |, which means or), and has two options:

  • ([0-9a-zA-Z])(?!\1): a letter or number, provided that it is not repeated
  • [!@#$%;*(){}_+^&]: one of the special characters

Thus, @@ is considered valid, but aa and 11 nay. See here the regex working.


You can read more about using regex to validate passwords here, here and here.

  • Dude, it worked perfectly! I’m still very young when it comes to working with regex and the like. Where do you think I could study better the use of it and perfect myself in this line of programming?

  • 1

    @lucasmenezes Two sites that I like quite are that and that. And books, I recommend that and that

Browser other questions tagged

You are not signed in. Login or sign up in order to post.