Регулярное выражение для проверки пароля: "8 символов, включая 1 заглавную букву, 1 специальный символ, буквенно-цифровые символы"

Я хочу, чтобы регулярное выражение проверяло, что

пароль должен содержать восемь символов, включая одну прописную букву, один специальный символ и буквенно-цифровые символы.

И вот мое выражение проверки, которое предназначено для восьми символов, включая одну прописную букву, одну строчную букву и один номер или специальный символ.

(?=^.{8,}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$"

Как я могу написать его для пароля, который должен содержать восемь символов, включая одну заглавную букву, один специальный символ и буквенно-цифровые символы?

Ответ 1

Регулярное выражение, которое вы после этого, скорее всего, будет огромным и кошмаром для поддержания особенно для людей, которые не знакомы с регулярными выражениями.

Я думаю, было бы легче сломать ваше регулярное выражение и сделать это по одному за раз. Это может потребоваться немного больше, но я уверен, что поддерживать его и отлаживать было бы проще. Это также позволит вам предоставлять более ориентированные сообщения об ошибках вашим пользователям (кроме как только Invalid Password), что должно улучшить работу пользователя.

Из того, что я вижу, вы довольно свободно владеете регулярным выражением, поэтому я бы предположил, что дать вам регулярные выражения, чтобы делать то, что вам нужно, было бы бесполезно.

Увидев ваш комментарий, я об этом подумал:

  • Должно быть восемь символов Long: для этого вам не нужно регулярное выражение. Использовать свойство .Length должно быть достаточно.

  • Включая одну прописную букву: вы можете использовать регулярное выражение [A-Z]+. Если строка содержит хотя бы одну букву верхнего регистра, это регулярное выражение даст true.

  • Один специальный символ: вы можете использовать либо \W, который будет соответствовать любому символу, который не является буквой или числом, или иначе, вы можете использовать что-то вроде этого [[email protected]#], чтобы указать собственный список специальных персонажи. Обратите внимание, что символы, такие как $, ^, ( и ) являются специальными символами на языке регулярных выражений, поэтому их необходимо экранировать следующим образом: \$. Короче говоря, вы можете использовать \W.

  • Буквенно-цифровые символы: использование \w+ должно соответствовать любой букве и числу и подчеркиванию.

Посмотрите этот учебник для получения дополнительной информации.

Ответ 2

(                   # Start of group
    (?=.*\d)        #   must contain at least one digit
    (?=.*[A-Z])     #   must contain at least one uppercase character
    (?=.*\W)        #   must contain at least one special symbol
       .            #     match anything with previous condition checking
         {8,8}      #        length is exactly 8 characters
)                   # End of group

В одну строку:

((?=.*\d)(?=.*[A-Z])(?=.*\W).{8,8})

Изменить 2019-05-28:

Вы должны соответствовать всей входной строке. Таким образом, вы можете заключить регулярное выражение между ^ и $, чтобы предотвратить случайное допущение частичного совпадения как совпадения с целым входом:

^((?=.*\d)(?=.*[A-Z])(?=.*\W).{8,8})$
Источники

:

Ответ 3

Так много ответов.... все плохо!

Регулярные выражения не имеют оператора И, поэтому довольно сложно написать регулярное выражение, которое соответствует действительным паролям, когда действительность определяется чем-то И что-то еще И что-то еще...

Но регулярные выражения имеют OR-оператор, поэтому просто примените теорему DeMorgan и напишите регулярное выражение, которое соответствует недопустимым паролям.

все, что меньше 8 символов ИЛИ все без цифр ИЛИ все без прописных букв ИЛИ все без специальных символов

Итак:

^(.{0,7}|[^0-9]*|[^A-Z]*|[a-zA-Z0-9]*)$

Если что-то соответствует этому, тогда это неверный пароль.

Ответ 4

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

Для более длинного регулярного выражения вы всегда должны использовать RegexOptions.IgnorePatternWhitespace, чтобы разрешить пробелы и комментарии в выражении для лучшей читаемости.

String[] passwords = { "foobar", "Foobar", "Foobar1", "Fooobar12" };

foreach (String s in passwords) {

    Match password = Regex.Match(s, @"
                                      ^              # Match the start of the string
                                       (?=.*\p{Lu})  # Positive lookahead assertion, is true when there is an uppercase letter
                                       (?=.*\P{L})   # Positive lookahead assertion, is true when there is a non-letter
                                       \S{8,}        # At least 8 non whitespace characters
                                      $              # Match the end of the string
                                     ", RegexOptions.IgnorePatternWhitespace);

    if (password.Success) {
        Console.WriteLine(s + ": valid");
    }
    else {
        Console.WriteLine(s + ": invalid");
    }
}

Console.ReadLine();

Ответ 5

Ответ заключается в том, чтобы не использовать регулярное выражение. Это наборы и подсчет.

Регулярные выражения имеют порядок.

В вашей жизни как программиста вы попросите сделать много вещей, которые не имеют смысла. Научитесь копать уровень глубже. Узнайте, когда вопрос неверен.

Вопрос (если он упоминает регулярные выражения) неверен.

Псевдокод (переключение между слишком многими языками в последнее время):

if s.length < 8:
    return False
nUpper = nLower = nAlphanum = nSpecial = 0
for c in s:
    if isUpper(c):
        nUpper++
    if isLower(c):
        nLower++
    if isAlphanumeric(c):
        nAlphanum++
    if isSpecial(c):
        nSpecial++
return (0 < nUpper) and (0 < nAlphanum) and (0 < nSpecial)

Ставка на то, что вы прочитали и поняли приведенный выше код почти мгновенно. Ставка на то, что вы занимали гораздо больше времени с регулярным выражением, и менее уверены, что это правильно. Расширение регулярного выражения является рискованным. Продвинуто сразу же, намного меньше.

Обратите внимание, что этот вопрос неточно сформулирован. Является ли набор символов ASCII или Unicode, или? Мое предположение, прочитав вопрос, состоит в том, что предполагается хотя бы один строчный символ. Поэтому я думаю, что принятое последнее правило должно быть:

return (0 < nUpper) and (0 < nLower) and (0 < nAlphanum) and (0 < nSpecial)

(Смена шляп в целях безопасности, это действительно раздражающее/не полезное правило.)

Учимся знать, когда вопрос неверен, является массово более важным, чем умные ответы. Умный ответ на неправильный вопрос почти всегда ошибочен.

Ответ 6

Если вам нужен только один верхний регистр и специальный символ, это должно работать:

@"^(?=.{8,}$)(?=[^A-Z]*[A-Z][^A-Z]*$)\w*\W\w*$"

Ответ 7

Регулярное выражение, которое вы искали, это: /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[[email protected]#\$%\^&\*\[\]"\';:_\-<>\., =\+\/\\]).{8,}$/u.

Пример и тест: http://regexr.com/3fhr4

Ответ 8

Этот вопрос начинает быть вирусным, и появилось много интересного предложения.

Да, писать вручную сложно. Таким образом, проще использовать шаблон. Хотя приведенное регулярное выражение может быть не самым оптимальным, его будет легче поддерживать и/или изменять, и пользователь будет лучше контролировать результат. Возможно, что я что-то пропустил, поэтому любая конструктивная критика будет полезна.

Эти ссылки могут быть интересными: сопоставить не менее 2 цифр 2 буквы в любом порядке в строке, Язык регулярных выражений, Захват групп

Я использую этот шаблон (?=(?:.*?({type})){({count})}) на основе всего регулярного выражения, которое я видел в SO. Следующий шаг - замена необходимого шаблона (number, special character...) и добавление конфигурации для длины.

Я сделал небольшой класс для компоновки регулярного выражения PasswordRegexGenerator.cs Пример:

string result = new PasswordRegexGenerator ( )
        .UpperCase ( 3, -1 )    // ... {3,}
        .Number ( 2, 4 )        // ... {2,4}
        .SpecialCharacter ( 2 ) // ... {2}
        .Total ( 8,-1 )
        .Compose ( );

/// <summary>
/// Generator for regular expression, validating password requirements.
/// </summary>
public class PasswordRegexGenerator
{
    private string _elementTemplate = "(?=(?:.*?({type})){({count})})";

    private Dictionary<string, string> _elements = new Dictionary<string, string> {
        { "uppercase", "[A-Z]" },
        { "lowercase", "[a-z]" },
        { "number", @"\d" },
        { "special", @"\W" },
        { "alphanumeric", @"\w" }
    };

    private StringBuilder _sb = new StringBuilder ( );

    private string Construct ( string what, int min, int max )
    {
        StringBuilder sb = new StringBuilder ( _elementTemplate );
        string count = min.ToString ( );

        if ( max == -1 )
        {
            count += ",";
        }
        else if ( max > 0 )
        {
            count += "," + max.ToString();
        }

        return sb
            .Replace ( "({type})", what )
            .Replace ( "({count})", count )
            .ToString ( );
    }

    /// <summary>
    /// Change the template for the generation of the regex parts
    /// </summary>
    /// <param name="newTemplate">the new template</param>
    /// <returns></returns>
    public PasswordRegexGenerator ChangeRegexTemplate ( string newTemplate )
    {
        _elementTemplate = newTemplate;
        return this;
       }

    /// <summary>
    /// Change or update the regex for a certain type ( number, uppercase ... )
    /// </summary>
    /// <param name="name">type of the regex</param>
    /// <param name="regex">new value for the regex</param>
    /// <returns></returns>
    public PasswordRegexGenerator ChangeRegexElements ( string name, string regex )
    {
        if ( _elements.ContainsKey ( name ) )
        {
            _elements[ name ] = regex;
        }
        else
        {
            _elements.Add ( name, regex );
        }
        return this;
    }

    #region construction methods 

    /// <summary>
    /// Adding number requirement
    /// </summary>
    /// <param name="min"></param>
    /// <param name="max"></param>
    /// <returns></returns>
    public PasswordRegexGenerator Number ( int min = 1, int max = 0 )
    {
        _sb.Append ( Construct ( _elements[ "number" ], min, max ) );
        return this;
    }

    public PasswordRegexGenerator UpperCase ( int min = 1, int max = 0 )
    {
        _sb.Append ( Construct ( _elements[ "uppercase" ], min, max ) );
        return this;
    }

    public PasswordRegexGenerator LowerCase ( int min = 1, int max = 0 )
    {
        _sb.Append ( Construct ( _elements[ "lowercase" ], min, max ) );
        return this;
    }

    public PasswordRegexGenerator SpecialCharacter ( int min = 1, int max = 0 )
    {
        _sb.Append ( Construct ( _elements[ "special" ], min, max ) );
        return this;
    }

    public PasswordRegexGenerator Total ( int min, int max = 0 )
    {
        string count = min.ToString ( ) + ( ( max == 0 ) ? "" : "," + max.ToString ( ) );
        _sb.Append ( ".{" + count + "}" );
        return this;
    }

    #endregion

    public string Compose ()
    {
        return "(" + _sb.ToString ( ) + ")";
    }
}

Ответ 9

Для проверки можно использовать класс ниже:

public class PasswordValidator{

  private Pattern pattern;
  private Matcher matcher;

  private static final String PASSWORD_PATTERN =
          "((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%]).{6,20})";

  public PasswordValidator(){
      pattern = Pattern.compile(PASSWORD_PATTERN);
  }

  /**
   * Validate password with regular expression
   * @param password password for validation
   * @return true valid password, false invalid password
   */
  public boolean validate(final String password){

      matcher = pattern.matcher(password);
      return matcher.matches();

  }
}

где 6 и 20 - минимальная и максимальная длина пароля.

Ответ 10

  • Сначала используйте выражение без обратного слежения, чтобы сначала сопоставить весь пароль, если оно имеет не менее 8 символов (таким образом, комбинаторный взрыв для длинных, но недействительных паролей отсутствует): (?>{8,})
  • Используйте утверждения "lookbehind" для проверки наличия всех необходимых символов (AND-условия). (?<=...)
  • Как минимум один заглавный символ: (?<=\p{Lu}.*)
  • По крайней мере, один специальный символ (немного двусмысленно, но позвольте использовать не-слово): (?<=\W.*)
  • Как минимум один буквенно-цифровой символ (: (?<=\w.*)

Подведены итоги:

(?>.{8,})(?<=\p{Lu}.*)(?<=\W.*)(?<=\w.*)

Ответ 11

/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}$/