我必须使用正则表达式验证密码。 密码规则至少为1个大写,至少为2个数字。
除非字符位于字符串的末尾,否则它可以正常工作。
我正在使用的正则表达式是
"^(?=.*\d.{2})(?=.*[A-Z].{1})(?=.*[@#$%^&+=].{2}).{8,12}$"
规则:
适用于Test123$$
,Test$123
,TEST123$s
,Test123$1
,Test12$3
但如果指定的字符位于字符串末尾,则会失败Test123$
,Test$a12
,Test12aa@
,123aa@@T
。
如果有任何解决方法,请告诉我。
答案 0 :(得分:2)
在你的正则表达式中,我看到了一些问题:
(?=.*\d.{2})
- 为什么第二个.
,你不能用{2}
检查两次出现,因为假设它们在附近...... Test1 $ 2 $ 3 < / em>也应该被允许...... (?=.*[A-Z].{1})
- 为什么第二个.
(?=.*[@#$%^&+=].{2})
- 再次,为什么第二个.
,为什么要检查2次? Spec说一个特殊的字符。尝试
"^(?=.*\d.*\d)(?=.*[A-Z])(?=.*[@#$%^&+=]).{8,12}$"
通过:
Debug.Assert( regex.IsMatch( "Test123$" ) );
Debug.Assert( regex.IsMatch( "Test123$$" ) );
Debug.Assert( regex.IsMatch( "$Test1$2" ) ); // two numbers, not following
Debug.Assert( regex.IsMatch( "Test$123" ) );
Debug.Assert( !regex.IsMatch( "Test12$" ) ); // 7 chars
Debug.Assert( !regex.IsMatch( "Test12345" ) ); // no special char
Debug.Assert( !regex.IsMatch( "Test$$$$" ) ); // no number
Debug.Assert( !regex.IsMatch( "Test$3$$" ) ); // only one number
Debug.Assert( !regex.IsMatch( "test12$$" ) ); // no upper case
答案 1 :(得分:1)
您的问题是您使用的是(atom).{length}
,长度适用于.
,而不是atom
。您应该使用(atom){length}
。其次,\d{2}
不是“最小数字:2”。这是“2个结果数字”。 «最小数字:2»看起来像这样:.*\d.*\d
,所以完整的正则表达式(注意(atom){1}
和(atom)
是相同的正则表达式):
^(?=.*\d.*\d)(?=.*[A-Z])(?=.*[@#$%\^&+=]).{8,12}$
并且,请将{8,12}
替换为{8,}
:您不应禁止用户输入长密码。
答案 2 :(得分:0)
您的要求列表未指定常规语言。因此,使用正则表达式进行匹配将很困难(如果不是不可能)。
答案 3 :(得分:0)
你不能为此创建一个有限状态机,所以(除非在实践中有关于正则表达式的理由不同于理论上),否则你将无法为此找到正则表达式。
主要是因为它涉及计数,这需要“记忆”,这是有限状态机所没有的。
编辑:显然,DFA“技术”已经取得了进展。看到这篇文章的评论。
答案 4 :(得分:0)
虽然你没有说你正在使用什么样的正则表达式,但我建议采用以下方法 - 如果不是最有效的 - 更具可读性和可维护性(例如仅使用Python):
>>> import string
>>> def valid(s):
return 8 <= len(s) <= 12 and \
any(c in string.ascii_uppercase for c in s) and \
sum(c in string.digits for c in s) >= 2 and \
any(c in string.punctuation for c in s)
>>> valid('abcdefA')
False
>>> valid('123aa@@T')
True
>>> valid('Test123$')
True
>>> valid('Test123_')
True