【问题标题】:Regex expression for password rules密码规则的正则表达式
【发布时间】:2012-05-30 13:21:18
【问题描述】:

我对密码规则有要求。以下是规则。

密码必须遵循以下准则:

  • 至少有八个字符
  • 包含这 4 个选项中的 3 个:小写字母、大写字母、数字或特殊字符
  • 当用户指定的密码不符合上述规则时,返回信息说明:

    密码长度必须至少为 8 个字符,并且包含以下 4 个选项中的 3 个:

    • 小写字母 (a-z)
    • 大写字母 (A-Z)
    • 数字 (0-9)
    • 特殊字符 (!@#$%^&')

请帮我获取一个正则表达式来处理上述情况。

感谢您的所有帮助。以下是我的要求的解决方案

if(password.matches("^(?=.*[0-9]).{1,}$")){
validCount++;
}
if(password.matches("^(?=.*[a-z]).{1,}$")){
validCount++;
}
if(password.matches("^(?=.*[A-Z]).{1,}$")){
validCount++;
}
if(password.matches("^(?=.*[@#$%^&+=]).{1,}$")){
validCount++;
}
return validCount >= 3 ? true : false;

谢谢, 拉姆基

【问题讨论】:

  • 我认为在没有正则表达式的情况下这样做会更有意义......或者使用 4 个单独的正则表达式(检查 4 个匹配项中的 3 个)。
  • 我会使用 4 个单独的正则表达式来执行此操作,并像 jahroy 所说的那样检查 4 个匹配项中的 3 个。 8 个字符长只是检查 strPassword.Length >= 8
  • [regex] password 的搜索结果有几十个。由于您显然没有自己尝试过,也许对这些进行回顾会让您入门。 :) 从本页右侧的Related 列表开始。
  • 不是一个真正的问题?模式匹配是正则表达式的目的。

标签: regex


【解决方案1】:

这是,如果你想要一个优雅的正则表达式,尽可能接近

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&'])[^ ]{8,}$

基本思想是使用一种称为“积极前瞻”的技术:

(?=.*PutHereWhatYouWantToAllow)

您的额外要求 4 分之 3 不容易用正则表达式解决,因为您基本上无法使它们计数。 您可以写出上述正则表达式的必要排列(告诉我它是否没有意义),但这会使正则表达式很长。 您可以做的是在代码中写出排列,以便正则表达式保持可维护性,因为您没有按字面重复模式。

如果你告诉我你的语言(C#?),我会试一试,因为这是一个很好的挑战。

更新 1

这里的正则表达式将匹配您的至少 3 个要求(也允许 4 个),只是为了挑战它。不要在生产中使用它,而是在语言中循环使用 cmets 中提到的单个正则表达式。

^((?=.[az].[AZ].[\d])|(?=.[az].[\ d].[AZ])|(?=.[AZ].[az].[\d])|(?=.[AZ ].[\d].[az])|(?=.[\d].[az].[AZ])|(?= .[\d].[AZ].[az])|(?=.[az].[AZ].[! @#$​​%^&'])|(?=.[az].[!@#$%^&'].[AZ])|(?=.[AZ].[az].[!@#$%^&'])|(?=.[AZ].[!@#$% ^&'].[az])|(?=.[!@#$%^&'].[az].[AZ])|(? =.[!@#$%^&'].[AZ].[az])|(?=.[az].[\ d].[!@#$%^&'])|(?=.[az].[!@#$%^&'].[\ d])|(?=.[\d].[az].[!@#$%^&'])|(?=.[\d ].[!@#$%^&'].[az])|(?=.[!@#$%^&'].[az] .[\d])|(?=.[!@#$%^&'].[\d].[az])|(?=. [AZ].[\d].[!@#$%^&'])|(?=.[AZ].[!@# $%^&'].[\d])|(?=.[\d].[AZ].[!@#$%^&'] )|(?=.[\d].[!@#$%^&'].[AZ])|(?=.[!@#$ %^&'].[AZ].[\d])|(?=.[!@#$%^&'].[\d]. [AZ]))[^]{8,}$

更新 2

这是在java中采取的方法

从我读到的 cmets 中,您正在测试如下

  • 小写“^[a-z]*$”;
  • 大写“^[A-Z]*$”;
  • digits="^[0-9]*$";

我不认为你在这里是在正确的轨道上。如果 所有 个字符都是小写的,而不仅仅是一个,小写只会报告成功。其余部分同理。

这些是 4 个单独的正则表达式,其中至少 3 个应该报告匹配

[a-z]
[A-Z]
\d
[!@#$%^&']

这里是密码不应该包含空格的测试

^[^ ]*$

至少 8 个字符的测试

.{8,}

所以我拆分需求而不是合并它们。这应该使代码更具可读性,特别是如果以正则表达式开头。

【讨论】:

  • 它说它必须有 4 个选项中的 3 个。
  • 感谢您的快速回复。我忘了提,它不应该接受空白字符。我不需要检查所有 4 个条件。其中任何 3 个就足够了。我不知道如何在正则表达式中添加条件(AND OR)。
  • @Ramki 我更新了正则表达式,因此它拒绝带有空格的密码。正则表达式不是编程语言,因此它们不支持 AND 和 OR,尽管您可以模拟其中的大多数条件(如果不是全部条件)。但它不能说出我的回答中解释的四分之三。最好在代码中进行排列。
  • @Ramki 我不会流利地使用 Java,但你有希望自己做的想法。
  • 没问题。在 java 循环中测试所有 4 个要求并在匹配 3 个时立即停止似乎比在一个怪物正则表达式中更易于维护。但我无法自拔,稍后会发布那个大的正则表达式。
【解决方案2】:

我会这样做:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ValidatePassword
{
    public static void main (String[] args)
    {
        String pw = "abaslkA3FLKJ";

        // create an array with 4 regex patterns

        Pattern [] patternArray = {
            Pattern.compile("[a-z]"),
            Pattern.compile("[A-Z]"),
            Pattern.compile("[0-9]"),
            Pattern.compile("[&%$#]")
        };

        int matchCount = 0;

        // iterate over the patterns looking for matches

        for (Pattern thisPattern : patternArray) {
            Matcher theMatcher = thisPattern.matcher(pw);        
            if (theMatcher.find()) {
                matchCount ++;
            }
        }

        if (matchCount >= 3) {
            System.out.println("Success");
        }

        else {
            System.out.println("Failure: only " + matchCount + " matches");
        }
    }
}

我只在第 4 个模式中添加了几个特殊字符...您必须根据需要对其进行修改。您可能需要使用反斜杠转义某些字符。您可能还想添加其他约束,例如检查是否没有空格。我将把它留给你。

【讨论】:

  • 关于第4个模式的特殊字符。您不需要根据正则表达式规则(以及 java )转义它们中的任何一个。他们唯一需要注意的是你不要把 ^ 放在第一位,因为这会否定字符类。
  • 谢谢。我知道这些都不需要转义字符。不确定OP最终添加了什么字符。不想测试所有的可能性......
  • @jahroy 非常感谢您的帮助。
猜你喜欢
  • 2018-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-18
相关资源
最近更新 更多