根据评论区的讨论以及问题本身,从根本上讲,为了解决这个问题,您需要的正则表达式应该是这样的:
/^(?=.*[a-z])(?=.*[A-Z])(?!.*[0-9])(?!.*[&~_%#@+=<>?!.,;:"`^(){}*|\/\\$])(?!.*\s).{2,40}$/
(?=.*[a-z]):确保至少包含一个小写字母。
(?=.*[A-Z]):确保至少包含一个大写字母。
(?!.*[0-9]):验证不包含数字。
(?!.[&~_%#@+=<>?!.,;:"^(){}|/\$])}:验证不包含特殊符号。
(?!.*\s):验证不包含空格。
.{2,40}:确保字符数量在2到40之间。
请注意:正则表达式可能会变得相当复杂且难以管理,特别是在你为不同条件组合多个前瞻断言时。对于某些测试(检查),分别独立进行通常会更具可读性和可维护性,特别是当你对每个条件有特定的错误消息或处理方式时。
更新:由于提问者指出我提供的正则表达式模式没有考虑到"FooBar"这样的情况,我编写了一个简单的脚本来进行测试。但我更推荐Wiktor提出的正则表达式模式,因为它简洁易读(我并不对此提出异议)。
import re
regex_wiktor = r"^(?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z])[a-zA-Z]{2,40}$"
regex_str1ng = r"^(?=.*[a-z])(?=.*[A-Z])(?!.*[0-9])(?!.*[&~_%#@+=<>?!.,;:\"`^(){}*|\/\\$])(?!.*\s).{2,40}$"
# Test strings
test_strings = ["Foobar", "fooBar", "Foobar123", "foo bar", "Foobar!", "Fo", "F" * 41, "foobar", "FOOBAR"]
def test_regex(pattern, test_strings):
return {string: bool(re.match(pattern, string)) for string in test_strings}
results_wiktor = test_regex(regex_wiktor, test_strings)
results_str1ng = test_regex(regex_str1ng, test_strings)
print(results_wiktor, results_str1ng)
Results:
({'Foobar': True,
'fooBar': True,
'Foobar123': False,
'foo bar': False,
'Foobar!': False,
'Fo': True,
'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF': False,
'foobar': False,
'FOOBAR': False},
{'Foobar': True,
'fooBar': True,
'Foobar123': False,
'foo bar': False,
'Foobar!': False,
'Fo': True,
'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF': False,
'foobar': False,
'FOOBAR': False})
更新2:我收回之前的话,当使用Wiktor Stribiżew的正则表达式模式时,“Foobar\n”被视为一个有效的字符串——如果换行符并非预期允许的字符,则这可能成为一个潜在问题;而我的正则表达式模式则不会将其视为有效。