用于检查 4 个不同字符组中的至少 3 个的正则表达式
Posted
技术标签:
【中文标题】用于检查 4 个不同字符组中的至少 3 个的正则表达式【英文标题】:Regex for checking that at least 3 of 4 different character groups exist 【发布时间】:2011-08-22 11:41:03 【问题描述】:我正在尝试编写密码验证器。
如何查看我提供的字符串是否包含至少 3 个不同的字符组?
检查它们是否存在很容易——但至少有 3 个?
至少八 (8) 个字符
至少三个不同的字符组
大写字母
小写字母
数字
特殊字符 !@#$%&/=?_.,:;-\
(我正在使用 javascript 进行正则表达式)
【问题讨论】:
顺便说一句,@Yonder,你为什么只需要一个正则表达式?你想把它放到一些 JS 验证控件上吗? 【参考方案1】:只是为了学习 - 这种要求是否可以在纯正则表达式中实现?
这将使它成为一个相当难以阅读(并因此维护!)的解决方案,但它是:
(?mx)
^
(
(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]) # must contain a-z, A-Z and 0-9
| # OR
(?=.*[a-z])(?=.*[A-Z])(?=.*[!@\#$%&/=?_.,:;\\-]) # must contain a-z, A-Z and special
| # OR
(?=.*[a-z])(?=.*[0-9])(?=.*[!@\#$%&/=?_.,:;\\-]) # must contain a-z, 0-9 and special
| # OR
(?=.*[A-Z])(?=.*[0-9])(?=.*[!@\#$%&/=?_.,:;\\-]) # must contain A-Z, 0-9 and special
)
.8, # at least 8 chars
$
一个(可怕的)Javascript 演示:
var pw = "aa$aa1aa";
if(pw.match(/^((?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])|(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%&\/=?_.,:;\\-])|(?=.*[a-z])(?=.*[0-9])(?=.*[!@#$%&\/=?_.,:;\\-])|(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%&\/=?_.,:;\\-])).8,$/))
print('Okay!');
else
print('Fail...');
打印:Okay!
,您可以在 Ideone 上看到。
【讨论】:
顺便说一句,我一直希望正则表达式能够存储模式。我发现自己多次重复使用模式,因为它不是一个有意义的选择。基本上,类似(?\A[a-z])
将\A
分配给[a-z]
。我猜我会继续做梦。
@Brad,这是一个好主意。当然,您可以从字符串构建您的模式并将它们连接起来并执行new RegExp(a+"@"+a)
,其中a
是预定义的模式字符串。 (但你可能已经意识到了......)
@BartKiers:这就是我一直在做的,只是为了便于维护,但很高兴看到“正则表达式宏”。也许在模式的开头强制定义,然后允许在该模式的持续时间内使用。 ;-)
@Brad,许多正则表达式爱好者会欢迎这种诡计(像我一样),但是,正如您可能知道的那样,对于每个正则表达式爱好者来说,可能有大约 10 人反对引入这种简短的-切入已经“难以阅读”的语言。 :)
@BartKiers:我同意,我们需要带回:labels
和goto
s 吗?而且您知道他们对使用正则表达式解决问题的看法:now you have two problems。 :咧嘴:【参考方案2】:
也可以参与其中:
String.prototype.isValidPW = function()
// First, check for at least 8 characters
if (this.length < 8) return false;
// next, check that we have at least 3 matches
var re = [/\d/, /[A-Z]/, /[a-z]/, /[!@#$%&\/=?_.,:;-]/], m = 0;
for (var r = 0; r < re.length; r++)
if ((this.match(re[r]) || []).length > 0) m++;
return m >= 3;
;
if ("P@ssW0rd".isValidPW()) alert('Acceptable!');
Demo
【讨论】:
不错的一个。请注意,您无需在字符类中转义.
、$
和 ?
。
@BartKiers:有趣的故事:我偶然逃脱了]
并且遇到了 JS 错误。有点困惑,模式没有被接受,我逃避了一切,一个一个地删除了`s。然后,头被抓了之后,我抓住了它,忘了躲开其余的东西。 :oops: ;-)
最酷的不是把它放在 String.proto 中,而是放在另一个对象中。并且还创建一次这些正则表达式,例如:jsfiddle.net/XnPb4
这是我最喜欢的解决方案,但所提供的解决方案都不能确保所有字符都是可接受的类型。例如,单引号 (') 会提示“可接受!”这里。我的快速解决方法是将返回更改为:return (m >= 3 && this.match(/^[0-9a-zA-Z!@#$%&\/=?_.,:;-]+$/));
【参考方案3】:
我假设您将针对不同的要求使用不同的正则表达式。在这种情况下,请告诉我以下内容是否适合您:
var e = password.match(/.8,/); //At least 8 chars
var a = password.match(/[0-9]+/); //numeric
var b = password.match(/[A-Z]+/); //Capitals
var c = password.match(/[a-z]+/); //small letters
var d = password.match(/[!@#\$%&/=?_.,:;-\\]+/); //special chars
if (a + b + c + d > 2 && e) // Success
else // Failure
【讨论】:
非常好用且简单易懂的解决方案。非常可读。谢谢。 只是为了学习 - 这种要求是否可以在纯正则表达式中实现? @Yonder:是和不是。您可以验证它是否具有[A-Z]
、[a-z]
、[0-9]
、[<special>]
,但不是 4 个中有 3 个(据我所知),而不会将其分解为单独的功能。
顺便说一句 - 是否有必要在放入字符类时转义字符,即。在 [] 括号中?
@Yonder:只有对正则表达式有意义的字符。例如句点 (.
) 表示“任何字符”,因此当您需要文字句点时,您可以使用 \.
。 $
(行尾)、/
(在这种情况下是因为它是模式包装器)、?
(表示字符是可选的或不贪婪的标志)、-
在一个类中([]
)表示相同范围,因此您可以在课程结束时使用它或将其转义,等等。【参考方案4】:
http://jsfiddle.net/aSsR8/6/
/**
* Function determine, wheter we have valid password
*
* @param String value
* @return Boolean
*/
function isValidPassword(value)
// Here we define all our params
var validLength = 8,
minSuccess = 3,
isNumeric = + /\d+/.test(value),
isCapitals = + /[A-Z]+/.test(value),
isSmall = + /[a-z]+/.test(value),
isSpecial = + /[!@#$%&\/=\?_\.,:;\-]+/.test(value);
if (value.length < validLength) // 8 symbols. We don`t need regexp here
return false;
if (isNumeric + isCapitals + isSmall + isSpecial < minSuccess)
return false;
return true;
document.writeln(isValidPassword('abc'));
document.writeln(isValidPassword('abc123ABC'));
document.writeln(isValidPassword('abc123!23'));
【讨论】:
从什么时候... = + ...
在赋值后使用算术运算符?
这是将类型转换为 int 的简写。我昨天在这里的某个地方看到了它:)【参考方案5】:
Crimson 的回答对我不起作用。这是我所拥有的。
var mystring = 'bLahbla\\';
var valid_char_count = 0;
var lc = mystring.match(/[a-z]+/);
var uc = mystring.match(/[A-Z]+/);
var dc = mystring.match(/[0-9]+/);
var sc = mystring.match(/[\!\@\#\$\%\&\=\?\_\.\,\:\;\-\\]/);
if( lc ) valid_char_count++;
if( uc ) valid_char_count++;
if( dc ) valid_char_count++;
if( sc ) valid_char_count++;
if( valid_char_count >= 3 ) /* success */
【讨论】:
【参考方案6】:这将在一个正则表达式中完成所有这些
^.*(?=.8,)(?=.*[a-z])(?=.*[A-Z])(?=.*[\d\W])(?=.*[!@#\$%&/=?_\.,:;-\\]).*$
【讨论】:
我应该补充一点,IE6 不支持前瞻 对我来说没有四分之三。此模式可接受“密码”和“密码”(缺少数字或特殊字符才有效)。 这个似乎对我有用...密码和密码对我来说失败了,但 PassW0rd 成功 IE6 确实支持前瞻;这只是马车,@ 987654321@。我不知道这是否已经修复,但我很确定它至少在 IE7 中仍然被破坏。解决方法是在其他前瞻之前进行最小长度检查 -(?=.8,)
- 您已经在做。
您是否需要两个 .* 模式匹配(1 个在前瞻之前,1 个在它们之后)?看来您只需要 1 '.*' 在 ^ 和 $ 之间。此外,这并不能确保您有 4 个课程中的 3 个。你**必须**有一个大写字符和一个小写字符;你必须至少有一个数字或特殊字符。例如,'pa$$w0rd' 不会匹配,即使它有 3 个类。以上是关于用于检查 4 个不同字符组中的至少 3 个的正则表达式的主要内容,如果未能解决你的问题,请参考以下文章
正则表达式,用于包含至少8个字符和至少1个非字母数字字符的密码