JavaScript正则表达式密码验证含有特殊字符

81

我正在尝试使用正则表达式验证密码。如果我们的所有字符都是字母,则会更新密码。我做错了什么?正则表达式正确吗?

function validatePassword() {
    var newPassword = document.getElementById('changePasswordForm').newPassword.value;
    var minNumberofChars = 6;
    var maxNumberofChars = 16;
    var regularExpression  = /^[a-zA-Z0-9!@#$%^&*]{6,16}$/;
    alert(newPassword); 
    if(newPassword.length < minNumberofChars || newPassword.length > maxNumberofChars){
        return false;
    }
    if(!regularExpression.test(newPassword)) {
        alert("password should contain atleast one number and one special character");
        return false;
    }
}

它为什么没有被评估? - João Silva
如果新密码应该包含至少一个数字和一个特殊字符,即使没有这些条件,密码也会被更新。我想我的正则表达式有问题。 - Srikanth Sridhar
2
你为什么要设置这样任意的最大长度? - ChaosPandion
20个回答

119

使用正向先行断言

var regularExpression = /^(?=.*[0-9])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*]{6,16}$/;

如果没有这两个正则表达式中的前瞻断言,你当前的正则表达式只匹配长度为6到16个字符的有效字符,并且它不能验证至少有一个数字和至少一个特殊字符。而上面的前瞻断言就是用来实现这一点的。

  • (?=.*[0-9]) - 断言字符串中至少有一个数字;
  • (?=.*[!@#$%^&*]) - 断言字符串中至少有一个特殊字符。

9
可以将正则表达式缩短为/^(?=.*[\d])(?=.*[!@#$%^&*])[\w!@#$%^&*]{6,16}$/ - sQVe
3
如果我想让字母也必须包含,该怎么做呢?将正则表达式修改为/^(?=.[0-9])(?=.[!@#$%^&])(?=.[a-zA-Z])[a-zA-Z0-9!@#$%^&*]{6,16}$/即可。 - Bhuvan
3
@Bhuvan,我使用了这个答案来改进提供的表达方式。首先,包括更多的特殊字符[空格、连字符、问号、斜杠、反斜杠],并且最重要的是,我增加了最小字符数,因为6个字符的密码非常不安全,特别是如果没有登录失败监控和/或2FA的支持。话虽如此,我得出了这个结果:^(?=.*[0-9])(?=.*[- ?!@#$%^&*\/\\])(?=.*[A-Z])(?=.*[a-z])[a-zA-Z0-9- ?!@#$%^&*\/\\]{8,30}$ - Antonino
1
我会将 [a-zA-Z0-9!@#$%^&*]{6,16} 更改为 .{6,16},这样您就可以输入 任何 字符(只要密码包含数字和特殊字符)。我不认为仅因为密码包含 + 就应该拒绝它。 - Ivar
需要一个大写字符,它对于大写字符无效。 - Sanat Gupta
显示剩余2条评论

57

我使用以下脚本来确保密码长度不少于8个字符,且至少包含一个符号、大写和小写字母以及一个数字

function checkPassword(str)
{
    var re = /^(?=.*\d)(?=.*[!@#$%^&*])(?=.*[a-z])(?=.*[A-Z]).{8,}$/;
    return re.test(str);
}

2
好的,很精确。这样做可以满足AWS Cognito用户池的默认密码策略要求。 - vahdet
运行良好!谢谢。 - Isuru Lakruwan
它不接受gg@@ghgHHGG33h作为有效密码。 - Ezequias Lopes
为什么您没有将“_”下划线作为特殊字符考虑进去呢? - Nijat Mursali

47
function validatePassword() {
    var p = document.getElementById('newPassword').value,
        errors = [];
    if (p.length < 8) {
        errors.push("Your password must be at least 8 characters"); 
    }
    if (p.search(/[a-z]/i) < 0) {
        errors.push("Your password must contain at least one letter.");
    }
    if (p.search(/[0-9]/) < 0) {
        errors.push("Your password must contain at least one digit."); 
    }
    if (errors.length > 0) {
        alert(errors.join("\n"));
        return false;
    }
    return true;
}

由于在检查字符和数字时缺少 [ ],下面的答案存在某些问题,这是正确的版本。


2
如果您想限制大写或小写,请添加以下内容:if (p.search(/[a-z]/) < 0) { errors.push("您的密码必须包含至少一个小写字母。") } if (p.search(/[A-Z]/) < 0) { errors.push("您的密码必须包含至少一个大写字母。") } - saada
这里有一个更加动态的解决方案,但基本上使用了相同的概念: https://jsfiddle.net/omnius/p6uxjntg/ - Scott Gartner

29

你可以为 JavaScript 验证自己制作正则表达式

    /^            : Start
    (?=.{8,})        : Length
    (?=.*[a-zA-Z])   : Letters
    (?=.*\d)         : Digits
    (?=.*[!#$%&? "]) : Special characters
    $/              : End



        (/^
        (?=.*\d)                //should contain at least one digit
        (?=.*[a-z])             //should contain at least one lower case
        (?=.*[A-Z])             //should contain at least one upper case
        [a-zA-Z0-9]{8,}         //should contain at least 8 from the mentioned characters

        $/)

Example:-   /^(?=.*\d)(?=.*[a-zA-Z])[a-zA-Z0-9]{7,}$/

4
这个XYZ@123的操作失败了。 - Saras Arya
15
@SarasArya 加上特殊字符中的 @,它就会开始运作。这并不是什么难题! - mumair
@SarasArya,要求至少包含1个小写字符。XYZ@123没有小写字符。 - Optimus

21

不要试图在一个步骤中完成过多的事情。保持每个规则的独立性。

function validatePassword() {
    var p = document.getElementById('newPassword').value,
        errors = [];
    if (p.length < 8) {
        errors.push("Your password must be at least 8 characters");
    }
    if (p.search(/[a-z]/i) < 0) {
        errors.push("Your password must contain at least one letter."); 
    }
    if (p.search(/[0-9]/) < 0) {
        errors.push("Your password must contain at least one digit.");
    }
    if (errors.length > 0) {
        alert(errors.join("\n"));
        return false;
    }
    return true;
}

13

密码正则表达式:

/^(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[a-zA-Z!#$%&? "])[a-zA-Z0-9!#$%&?]{8,20}$/

我花了一些时间才想出所有的限制条件,但最终做到了!

限制条件: (注意:我使用>><<来显示重要字符)

  1. 至少8个字符 {>>8,20}
  2. 最多20个字符 {8,>>20}
  3. 至少一个大写字母 (?=.*[A-Z])
  4. 至少一个小写字母 (?=.*[a-z])
  5. 至少一个数字 (?=.*\d)
  6. 至少一个特殊字符 (?=.*[a-zA-Z >>!#$%&? "<<])[a-zA-Z0-9 >>!#$%&?<< ]

'@'和'^'符号怎么样? - prahack
1
/(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[a-zA-Z!#$@^%&? "])[a-zA-Z0-9!#$@^%&?]{8,20}$/ - Suwadith
1
特殊字符要求不起作用。 - Javano Collins

9

在这里,我在扩展@João Silva的答案。 我需要检查不同的参数并根据情况抛出不同的消息。

我将正则表达式分成不同的部分,现在checkPasswordValidity(String)函数有条件地检查每个正则表达式部分,并抛出不同的消息。

希望以下示例将帮助您更好地理解!

/**
 * @param {string} value: passwordValue
 */
const checkPasswordValidity = (value) => {
  const isNonWhiteSpace = /^\S*$/;
  if (!isNonWhiteSpace.test(value)) {
    return "Password must not contain Whitespaces.";
  }

  const isContainsUppercase = /^(?=.*[A-Z]).*$/;
  if (!isContainsUppercase.test(value)) {
    return "Password must have at least one Uppercase Character.";
  }

  const isContainsLowercase = /^(?=.*[a-z]).*$/;
  if (!isContainsLowercase.test(value)) {
    return "Password must have at least one Lowercase Character.";
  }

  const isContainsNumber = /^(?=.*[0-9]).*$/;
  if (!isContainsNumber.test(value)) {
    return "Password must contain at least one Digit.";
  }

  const isContainsSymbol =
    /^(?=.*[~`!@#$%^&*()--+={}\[\]|\\:;"'<>,.?/_₹]).*$/;
  if (!isContainsSymbol.test(value)) {
    return "Password must contain at least one Special Symbol.";
  }

  const isValidLength = /^.{10,16}$/;
  if (!isValidLength.test(value)) {
    return "Password must be 10-16 Characters Long.";
  }

  return null;
}

//------------------
// Usage/Example:
let yourPassword = "yourPassword123";
const message = checkPasswordValidity(yourPassword);

if (!message) {
  console.log("Hurray! Your Password is Valid and Strong.");
} else {
  console.log(message);
}

此外,我们可以将所有这些正则表达式模式组合成单个正则表达式:

let regularExpression = /^(\S)(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])(?=.*[~`!@#$%^&*()--+={}\[\]|\\:;"'<>,.?/_₹])[a-zA-Z0-9~`!@#$%^&*()--+={}\[\]|\\:;"'<>,.?/_₹]{10,16}$/;

注意: 上述正则表达式将检查给定输入值/密码中的以下模式:

  • 它不能包含任何空格。
  • 它必须包含至少一个大写字母、一个小写字母和一个数字字符。
  • 它必须包含至少一个特殊字符。[~`!@#$%^&*()--+={}[]|\:;"'<>,.?/_₹]
  • 长度必须介于10到16个字符之间。

谢谢!


6

国际化UTF-8

这里的解决方案都不能处理国际字符,比如éÉáÁöÖæÆþÞóÓúÚ,只能处理英文字母。

以下正则表达式使用Unicode UTF-8来识别大小写,从而允许处理国际字符:

// Match uppercase, lowercase, digit or #$!%*?& and make sure the length is 8 to 96 in length  
const pwdFilter = /^(?=.*\p{Ll})(?=.*\p{Lu})(?=.*[\d|@#$!%*?&])[\p{L}\d@#$!%*?&]{8,96}$/gmu

if (!pwdFilter.test(pwd)) {
    // Show error that password has to be adjusted to match criteria
}

这个正则表达式

/^(?=.*\p{Ll})(?=.*\p{Lu})(?=.*[\d|@#$!%*?&])[\p{L}\d@#$!%*?&]{8,96}$/gmu

检查密码中是否使用了大写字母、小写字母、数字或 #$!%*?&,同时限制密码长度最小为 8 个字符,最大为 96 个字符。表情符号的长度算作多于一个字符。最后的 u 表示使用 UTF-8 编码。


这对一些Unicode字符有效,但对于例如西里尔字母或中文字符(可能还包括阿拉伯字符)无效。在国际环境中,这些字符都可能被期望包含在内。您能否改进正则表达式以包括这些字符? - undefined
@user9128309 你需要更具体地说明哪些字符(字形)无法正常工作,否则你会让我花费大量时间去调查我对其了解有限的语言。 - undefined
好的观点:您可以使用以下内容作为测试案例。大多数国际用户将使用他们的母语创建密码。还请注意,密码中可能会包含中文和拉丁字母的组合。const pass3 = "Тест123...+*"; //西里尔字母 const pass4 = "关键字157aA$89!"; //普通话 const pass5 = "كلمة_سرية@123"; //阿拉伯语 const pass6 = "¿1-CómosediceAlbertoespañol?"; //西班牙语 - undefined

4
<div>
    <input type="password" id="password" onkeyup="CheckPassword(this)" />
</div>   

<div  id="passwordValidation" style="color:red" >
    
</div>

 function CheckPassword(inputtxt) 
    { 
    var passw= /^(?=.*\d)(?=.*[a-z])(?=.*[^a-zA-Z0-9])(?!.*\s).{7,15}$/;
    if(inputtxt.value.match(passw)) 
    { 
    $("#passwordValidation").html("")
    return true;
    }
    else
    { 
    $("#passwordValidation").html("min 8 characters which contain at least one numeric digit and a special character");
    return false;
    }
    }

3

经过大量的研究,我设法想出了这个解决方案。它包含更多的特殊字符。

validatePassword(password) {
        const re = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*()+=-\?;,./{}|\":<>\[\]\\\' ~_]).{8,}/
        return re.test(password);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接