2016-05-04 13 views
-1

私はこれらのルールにパスワード文字列をチェックアウトする必要があります。これらの2つの正規表現をマージする方法はありますか?

  • のみ、小文字、大文字、数字、一部の特殊文字が(下記参照)が許可されています。

    • 小文字
    • 大文字
    • :8つの文字と16
    • パスワード必見の最大の

    • Minimunは、次の4つのグループの3から少なくとも1つの文字が含まれています
    • 数値文字
    • 特殊文字(@#$%&/= _、:!?。;-)

この目的を達成するために、2つの検証を行いました。簡単なものは、許可された文字とな長さをチェックアウトする最初のステップです:

^[[email protected]\#$%&/=?_.,:;\-]{8,16}$ 

をもう一つはもう少し複雑ですが、私はそれをこのStackoverflow answerのおかげで解決することができます:

^((?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])|(?=.*[a-z])(?=.*[A-Z])(?=.*[[email protected]\#$%&/=?_.,:;\-])|(?=.*[a-z])(?=.*[0-9])(?=.*[[email protected]\#$%&/=?_.,:;\-])|(?=.*[A-Z])(?=.*[0-9])(?=.*[[email protected]\#$%&/=?_.,:;\-])).{8,16}$ 

私はおそらく、2ステップの解決策は明らかで簡単だと思いますが... 正規表現をマージする方法はありますか?

Java、JavaScript、およびLuaでこのソ​​リューションを適用したいと思います。

答えて

1

私はあなたのパスワードポリシーを嫌うことを強調してから始めましょう。 16文字を超える他のシンボルやパスワードを禁止するのはなぜですか?可能であれば、これらのルールは含めないでください。

私は明確にするため、(すなわち、ホワイトスペースは無視)拡張形式でこの正規表現を書いた:

/\A 
    (?=.{8,16}\z)      # Must contain 8-16 characters 
    (?!.*[^a-zA-Z\[email protected]#$%&\/=?_.,:;-]) # Must not contain other characters 
    (?=.*\d)       # Must contain a digit 
    (?=.*[a-z])      # Must contain a lower case character 
    (?=.*[A-Z])      # Must contain an upper case character 
    (?=.*[[email protected]#$%&\/=?_.,:;-])   # Must contain a symbol from this list 
/x 

上記のパターンは、あなたのルールのすべての4つのを実施するための問題を解決します。理論的には、元の例が行ったように、最後の4つの条件を4つの "または"グループにまとめることができます。

しかし、もう一度お勧めしません。関数内で一連の個別のチェックとしてこれを行うと、あなたのコードははるかに読みやすく、有用でメンテナンス可能になります。 (例えば、これは単に "正規表現が失敗しました!"よりも役に立つエラーメッセージを表示できることを意味します。

ここでは正規表現のモンスターは次のとおりです。あなたは/が/x修飾子へのアクセスを持ってしたくない場合は

/\A 
    (?=.{8,16}\z) 
    (?!.*[^a-zA-Z\[email protected]#$%&\/=?_.,:;-]) 
    (
    (?=.*\d) 
    (?=.*[a-z]) 
    (?=.*[A-Z]) 
    | 
    (?=.*\d) 
    (?=.*[a-z]) 
    (?=.*[[email protected]#$%&\/=?_.,:;-]) 
    | 
    (?=.*\d) 
    (?=.*[A-Z]) 
    (?=.*[[email protected]#$%&\/=?_.,:;-]) 
    | 
    (?=.*[a-z]) 
    (?=.*[A-Z]) 
    (?=.*[[email protected]#$%&\/=?_.,:;-]) 
) 
/x 

は、すべての空白を削除します。

+0

パスワードポリシーは私の要求事項であり、他のシステムでこのポリシーを実装しているため、現在変更することは非常に困難です。ソリューションとアドバイスをお寄せいただきありがとう@TomLord! –

0

この完全な検証のための1つの正規表現の欠点は、正規表現が読み込みおよび維持が非常に困難になることです。正規表現の条件を各条件ごとに1つのチェックに区切り、文字列の長さを単純にチェックすることは、より合理的で読みやすい解決策になります。私の意見では、次のコードは、パスワードの検証を単一の正規表現と同じくらいうまく行っていますが、維持して読み込む方が良いです。

public static void main(String[] args) { 
    System.out.println(isPasswordValid("Ab$123456")); 
    System.out.println(isPasswordValid("b$11234566")); 
    System.out.println(isPasswordValid("Ab$1234634634534252")); 
    System.out.println(isPasswordValid("$112512312512")); 
    System.out.println(isPasswordValid("A$115 223")); 
} 

private static boolean isPasswordValid(String password) { 
    // The password is to short or to long 
    if(password.length() < 8 || password.length() > 16) { 
     return false; 
    } 
    int matchedConditions = 0; 
    // Check for invalid characters 
    if(password.matches(".*[^A-Za-z0-[email protected]#$%&/=?_.,:;-].*")) { 
     return false; 
    } 
    // is an uppercase letter present, increase matched condition 
    if(password.matches(".*[A-Z].*")){ 
     ++matchedConditions; 
    } 
    // is a lowercase letter present, increase matched condition 
    if(password.matches(".*[a-z].*")){ 
     ++matchedConditions; 
    } 
    // is a numeric value present, increase matched condition 
    if(password.matches(".*[0-9].*")){ 
     ++matchedConditions; 
    } 
    // is a special character present, increase matched condition 
    if(password.matches(".*[[email protected]#$%&/=?_.,:;-].*")){ 
     ++matchedConditions; 
    } 
    // Return if at least 3 conditions were met 
    return matchedConditions >= 3; 
} 

出力:

true 
true 
false 
false 
false 
+0

ありがとうございますが、あなたのソリューションはこのパスワード 'Ab $ 12 34'に対して真を返すでしょう。スペースは許されませんよね? –

+0

@DavidIslaは私の編集をチェックしていますが、無効な文字のリストを含めると読みやすくなります。 – SomeJavaGuy

+0

確かに、あなたのソリューションは有効です。そうですが、両方をマージする方法があるかどうかを知りたいのです。どうもありがとう! –

関連する問題