Regex special characters required

Asked

Viewed 7,370 times

0

I need to create a regex to validate password.

It must contain at least 8 characters, of which it must have at least 1 letter, 1 number and 1 special character.

  • 1

    Marcelo, I believe that this type of question has already been answered dozens of times and you can find the answer on Google. See this link

  • 2

    Required reading for those in the area: https://xkcd.com/936/ ; if you want to use this security scheme, be aware that it is bankrupt by definition. The only way to ensure that the entropy of the password makes it strong against brute attacks is with its size. The strength to break a password d digits over an alphabet of A distinct characters is O(A**d); hence, if you just climb the A, how much you gain in complexity is waning in the face of the increase in the number of digits

  • It’s not exactly what you want (it’s almost) but you already have an idea: https://answall.com/a/337981/112052 - and on special characters: https://answall.com/a/342737/112052

  • what do you consider a special character friend? could list some examples?

  • Personal thank you

2 answers

1


Regex Usada

This regex does the validation, you can test it here:

(?=.*[}{,.^?~=+\-_\/*\-+.\|])(?=.*[a-zA-Z])(?=.*[0-9]).{8,}

Remembering that you should use double escape where it has the character \, so in Java code all backslashes must be double \\.


Application in Java code

In Java code you can validate with String.matches, the way I showed below:

public class JavaFiddle
{
   public static void main(String[] args)
   {
     System.out.println("A{123456".matches("(?=.*[}{,.^?~=+\\-_\\/*\\-+.\\|])(?=.*[a-zA-Z])(?=.*[0-9]).{8,}")); //exemplo que passa
     System.out.println("ASD1ASDA".matches("(?=.*[}{,.^?~=+\\-_\\/*\\-+.\\|])(?=.*[a-zA-Z])(?=.*[0-9]).{8,}")); //exemplo que nao passa (falta caractere especial)
     System.out.println("ASDAS^^?".matches("(?=.*[}{,.^?~=+\\-_\\/*\\-+.\\|])(?=.*[a-zA-Z])(?=.*[0-9]).{8,}")); //exemplo que nao passa (falta numero)
     System.out.println("123^8542".matches("(?=.*[}{,.^?~=+\\-_\\/*\\-+.\\|])(?=.*[a-zA-Z])(?=.*[0-9]).{8,}")); //exemplo que nao passa (falta letra)
     System.out.println("WWEA^^1".matches("(?=.*[}{,.^?~=+\\-_\\/*\\-+.\\|])(?=.*[a-zA-Z])(?=.*[0-9]).{8,}")); //exemplo que nao passa (nao tem minimo de 8 caracteres)
   }
}

This code displays true on the console when it is a valid standard, and false for invalid patterns.
You can test this code on Javafiddle like I did too, just copy and paste the code from that reply.

NOTE: As it was not specified which would be the special characters I used as valid the following characters (,.^?~=+-_/*\+)
You can change the characters that enter as special characters in this part of regex:
(?=.*[}{,.^?~=+\-_\/*\-+.\|]), just don’t take the part (?= ... ), because it signals a Positive Lookahead, which is required to validate that there is at least one of the characters flagged in the group before starting capture.


Explanation by Regex

  • (?=.*...) - Is a Positive Lookahead which will ensure that the following character group MUST be in the string for it to be validated.
  • [}{,.^?~=+\-_\/*\-+.\|] - Is the set defining which characters can be captured by Positive Lookahead.
  • (?=.*...) - Is a Positive Lookahead which will ensure that the following character group MUST be in the string for it to be validated.
  • [a-zA-Z] - It is the set that characterizes any letter character being uppercase or lowercase.
  • (?=.*...) - Is a Positive Lookahead which will ensure that the following character group MUST be in the string for it to be validated.
  • [0-9] - It is the set that characterizes any number between 0 and 9.
  • .{8,} - After these validations, a sequence of any character that does not contain line breaks will be captured (signaled by .).
    And a minimum length of 8 characters (marked by {8,}), no maximum limit (if you want to set a limit you can put the maximum number of character after the ,).

EDITED
Thank you to the user @hkotsubo for warning me of my mistake

  • In fact the . accepts yes spaces, see here. And accept any other character that has not been specified previously: https://regex101.com/r/8rtOcc/2/ (not that this is a problem, since the question does not make clear what it is to have or not to have)

  • 1

    @hkotsubo then you got me kkk, I meant line break, my mistake. I’ll fix.

  • 1

    It is, by default the . does not consider line breaks. But - out of curiosity - it is possible to make you consider, using the option DOTALL: https://ideone.com/rAxncr

  • Top thank you so much!

  • @Marcelo consider marking the answer as correct, if she answered your initial question

0

Good afternoon.

I’m using Fluentvalidation and I made some validations for password today. See if this helps you (If you have any questions about the code tell me):

using FluentValidation;
using System.Linq;
using System.Text.RegularExpressions;

namespace SaleTheaterTickets.Models.ViewModelValidators
{
    public class RegisterViewModelValidator : AbstractValidator<RegisterViewModel>
    {
        public RegisterViewModelValidator()
        {
            RuleFor(x => x.Email)
                .NotEmpty().WithMessage("Informe o e-mail")
                .EmailAddress().WithMessage("Digite um e-mail válido ([email protected])");
            RuleFor(x => x.Password)
                .NotEmpty().WithMessage("Informe a senha")
                .Length(6, 20).WithMessage("Senha deve ter no mínimo 6 e no máximo 20 caractéres")
                .Must(RequireDigit).WithMessage("Senha deve ter pelo menos 1 número")
                .Must(RequiredLowerCase).WithMessage("Senha deve ter pelo menos 1 caracter minúsculo")
                .Must(RequireUppercase).WithMessage("Senha deve ter pelo menos 1 caracter maiúsculo")
                .Must(RequireNonAlphanumeric).WithMessage("Digite pelo menos 1 caracter especial (@ ! & * ...)");
            RuleFor(x => x.ConfirmPassword)
                .NotEmpty().WithMessage("Confirme a senha")
                .Equal(x => x.Password).WithMessage("Senhas não conferem");
        }

        private bool RequireDigit(string password)
        {
            if (password.Any(x => char.IsDigit(x)))
            {
                return true;
            }
            return false;
        }

        private bool RequiredLowerCase(string password)
        {
            if (password.Any(x => char.IsLower(x)))
            {
                return true;
            }
            return false;
        }

        private bool RequireUppercase(string password)
        {
            if (password.Any(x => char.IsUpper(x)))
            {
                return true;
            }
            return false;
        }

        private bool RequireNonAlphanumeric(string password)
        {
            //if (password.Any(x => char.IsSymbol(x)))
            //{
            //    return true;
            //}
            //return false;

            if (Regex.IsMatch(password, "(?=.*[@#$%^&+=])"))
            {
                return true;
            }
            return false;
        }
    }
}

NOTE: The methods are English, but they serve the following:

Requiredigit - at least 1 number in the password Requiredlowercase - at least 1 lower case letter in password Requireuppercase - at least 1 uppercase letter in password Requirenonalphanumeric - at least one special character in the password

NOTE: Asp.Net Core Identity already does these checks, but I was not able to translate the messages that came as default, so I took and created each validation by myself (following the validations I saw in the documentation that Identity does for password) in order to generate my sentences in Portuguese.

I hope it helps you somehow!

Browser other questions tagged

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