web-dev-qa-db-ja.com

パスワードが「大文字1文字、特殊文字1文字、英数字1文字を含む8文字」であるかどうかを調べる正規表現

それをチェックするための正規表現が欲しい

パスワードは、大文字1文字、特殊文字1文字、英数字を含む8文字でなければなりません。

そして、これが私の検証式で、大文字1文字、小文字1文字、数字または特殊文字1文字を含む8文字です。

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

1文字の大文字、1文字の特殊文字、および英数字を含む8文字でなければならないパスワードに対してどのようにそれを書くことができますか?

100
Rania Umair

特に正規表現に慣れていない人にとっては、あなたが期待している正規表現はおそらく巨大で悪夢のようなものになるでしょう。

正規表現を分割して一度に1つずつ実行するほうが簡単だと思います。もう少し時間がかかるかもしれませんが、保守とデバッグが容易になると確信しています。これはまた、あなたがあなたのユーザに対してより直接的なエラーメッセージを提供することを可能にするでしょう(単にInvalid Password以外)、それはユーザエクスペリエンスを改善するはずです。

私はあなたが正規表現にかなり流暢であることを見ていることから、私はあなたがあなたが必要とすることをするためにあなたに正規表現を与えることは無益であろうと思います。

あなたのコメントを見て、これは私がそれについてどうやって行くかです:

  • 長さは8文字でなければなりません:これには正規表現は必要ありません。 .Lengthプロパティを使用すれば十分です。

  • 大文字を1つ含める:[A-Z]+正規表現を使用できます。文字列に少なくとも1つの大文字が含まれる場合、この正規表現はtrueになります。

  • 1つの特殊文字:文字でも数字でもない任意の文字に一致する\Wを使用するか、そうでなければ特殊文字のカスタムリストを指定するために[!@#]のようなものを使用できます。ただし、$^()などの文字は、正規表現言語では特殊文字であるため、\$のようにエスケープする必要があります。要するに、あなたは\Wを使うかもしれません。

  • 英数字:\w+を使用すると、任意の文字、数字、および下線に一致するはずです。

詳細については this tutorialを見てください。

130
npinti
(                   # 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})

出典:

96
mmdemirbas

とてもたくさんの答え……すべて悪い!

正規表現はAND演算子を持っていないので、有効性が何かAND何か他のものAND何か他のものによって定義されている場合、有効なパスワードに一致する正規表現を書くのはかなり難しいです。

しかし、正規表現 do にはOR演算子があるので、DeMorganの定理を適用し、 invalid パスワードに一致する正規表現を書くだけです。

8文字未満のもの _または_ 数字のないもの _または_ 大文字のないもの _または_ 特殊文字のないもの

そう:

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

何かがそれに一致するならば、それは 無効な パスワードです。

28
Matt Timmermans

例として、これが可読/維持可能な正規表現でどのように行われることができるか。

長い正規表現では読みやすくするために式の中に空白やコメントを入れるために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();
10
stema

答えは正規表現を使わないことです。これは設定とカウントです。

正規表現は秩序についてです。

プログラマーとしてのあなたの人生では、意味をなさない多くのことをするように頼まれるでしょう。より深くレベルを掘ることを学びなさい。質問が間違っているときに学びましょう。

質問(正規表現に言及している場合)は間違っています。

疑似コード(最近では、多すぎる言語を切り替えていました):

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、または??質問を読んで私の推測は、少なくとも1つの小文字が想定されることです。それで私は仮定された最後の規則があるべきだと思います:

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

(セキュリティを重視したものに変更すると、これは 本当に 迷惑な/役に立たない規則です。)

質問が間違っているときを知ることを学ぶことは、賢い答えよりもはるかに重要です。間違った質問に対する賢い答えは、ほとんどいつも間違っています。

大文字と特殊文字が1つだけ必要な場合は、これでうまくいくはずです。

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

あなたが探していた正規表現は/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*\[\]"\';:_\-<>\., =\+\/\\]).{8,}$/uです。

例とテスト: http://regexr.com/3fhr4

1
Lucas

以下のクラスを検証に使用できます。

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は、パスワードの最小長と最大長です。

0
amit pandya

この質問は話題になり始め、多くの興味深い提案が現れました。

はい、手で書くのは難しいです。したがって、より簡単な解決策はテンプレートを使用することです。結果として得られた正規表現は最も最適ではないかもしれませんが、それを維持および/または変更することはより容易であり、そしてユーザーは結果に対してより良いコントロールを持つでしょう。私が何かを逃した可能性があるので、どんな建設的な批判も役に立つでしょう。

このリンクは面白いかもしれません: 文字列の中の任意の順番で少なくとも2桁の2文字にマッチ正規表現言語グループのキャプチャ

私はSOで見たすべての正規表現に基づいてこのテンプレート(?=(?:.*?({type})){({count})})を使っています。次のステップは、必要なパターン(numberspecial 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 ( ) + ")";
    }
}
0
Bakudan