0

次の正規表現を使用しています。(?=.+[az])(?=.+[AZ])(?=.+[^a-zA-Z]).{8,}

私の目標は、以下の 4 つのプロパティのうち 3 つを持つパスワードを持つことです。

大文字、小文字、数字、特殊文字

http://rubular.com/r/i26nwsTcaUhttp://regexlib.com/RETester.aspxを使用して、次の入力で式をテストしています

P@55w0rd
password1P
Password1
paSSw0rd

これらはすべてパスするはずですが、2 番目と 4 番目だけがhttp://rubular.com/r/i26nwsTcaUでパスし、すべてhttp://regexlib.com/RETester.aspxでパスします。

検証に使用している次のコードもあります

private void doValidate(String inputStr,String regex) {
    Pattern pattern = Pattern.compile(regex);
    if(!pattern.matcher(inputStr).matches()){
        String errMessage = "";
        throw new UniquenessConstraintViolatedException(errMessage);
    }
}

このコードは、合格するはずの「Password1」の検証に失敗します。表現に関しては、私はこのように理解しています

must have lower (?=.+[a-z])
must have upper (?=.+[A-Z])
must have non alpha (?=.+[^a-zA-Z])
must be eight characters long .{8,}

誰が私が間違っているのか教えてもらえますか。

前もって感謝します。

4

4 に答える 4

1

本質的に、.+部分式は非難されるべきであり、そうあるべきです.*。それ以外の場合、先読み部分は小文字、大文字、または英字以外を探しますが、文字列の最初の文字である場合、対応する各タイプの文字はカウントされません。したがって、パスワードではなく、最初の文字が切り捨てられたパスワードを検証しています。@Cfreakは正しくありませんが、彼は近いです-あなたがしていることは通常の正規表現では不可能であり、彼が提案するものを使用する必要があります. 先読みグループを使用する(?=)と、必要なことを行うことができます。それでも、個人的には@Cfreakが示唆するようにコーディングしたいと思います-読みやすく、コードから意図が明確になります。複雑な正規表現は、書くのが難しい傾向がありますが、しばらくすると読み取り、デバッグ、または改善するのはほぼ不可能です。

于 2012-05-11T18:34:20.757 に答える
0

私はそのような正規表現を使用しません。

  • わかりにくい
  • デバッグが難しい
  • 伸びにくい
  • あなたはその結果で多くを行うことはできません

クライアントにパスワードの何が問題なのかを伝えたい場合は、パスワードをもう一度調査する必要があります。実際の環境では、外国のロケールの文字をサポートしたい場合があります。

import java.util.*;
/**
    Pwtest

    @author Stefan Wagner
    @date Fr 11. Mai 20:55:38 CEST 2012
*/
public class Pwtest
{

    public int boolcount (boolean [] arr) {
        int sum = 0;
        for (boolean b : arr) 
            if (b) 
                ++sum;
        return sum;
    }

    public boolean [] rulesMatch (String [] groups, String password) {
        int idx = 0;
        boolean [] matches = new boolean [groups.length];
        for (String g: groups) {
            matches[idx] = (password.matches (".*" + g + ".*"));
            ++idx;
        }
        return matches;     
    }

    public Pwtest ()
    {
        String [] groups = new String [] {"[a-z]", "[A-Z]", "[0-9]", "[^a-zA-Z0-9]"};
        String [] pwl = new String [] {"P@55w0rd", "password1P", "Password1", "paSSw0rd", "onlylower", "ONLYUPPER", "1234", ",:?!"};
        List <boolean[]> lii = new ArrayList <boolean[]> ();
        for (String password: pwl) {
            lii.add (rulesMatch (groups, password)); 
        }

        for (int i = 0 ; i < lii.size (); ++i) {
            boolean [] matches = lii.get (i); 
            String pw = pwl[i];
            if (boolcount (matches) < 3) {
                System.out.print ("Password:\t" + pw + " violates rule (s): ");
                int idx = 0; 
                for (boolean b: matches) {
                    if (! b) 
                        System.out.print (groups[idx] + " "); 
                    ++idx;
                }
                System.out.println (); 
            }
            else System.out.println ("Password:\t" + pw + " fine ");
        }
    }

    public static void main (String args[])
    {
        new Pwtest ();
    }
}

出力:

Password:   P@55w0rd fine 
Password:   password1P fine 
Password:   Password1 fine 
Password:   paSSw0rd fine 
Password:   onlylower violates rule (s): [A-Z] [0-9] [^a-zA-Z0-9] 
Password:   ONLYUPPER violates rule (s): [a-z] [0-9] [^a-zA-Z0-9] 
Password:   1234 violates rule (s): [a-z] [A-Z] [^a-zA-Z0-9] 
Password:   ,:?! violates rule (s): [a-z] [A-Z] [0-9] 
Password:   Übergrößen345 fine 
Password:   345ÄÜö violates rule (s): [a-z] [A-Z]
于 2012-05-11T19:51:52.827 に答える
0

現在の正規表現では、1 つ以上の小文字、1 つ以上の大文字、1 つ以上の大文字または小文字、8 文字以上が続く必要があります。

特定の文字が表示される場所を指定しない限り、正規表現は AND を実行できません。基本的に、正規表現の各部分を独自の正規表現に分割し、それぞれをチェックする必要があります。長さは、Java の文字列長メソッドで確認できます (申し訳ありませんが、私は Java 開発者ではないので、頭から離れていることはわかりません)。

擬似コード:

if( regexForLower && regexForUpper && regexForSpecial && string.length == 8 ) {
     // pass
}
于 2012-05-11T18:18:10.800 に答える
0

コメントで述べたように、位置 0 の大文字は無視されています。

4 つのパスワードすべてが一致する正規表現を次に示します。

(?=.+\\d)(?=.+[a-z])(?=\\w*[A-Z]).{8,}
于 2012-05-11T18:22:15.980 に答える