至少包含 x 个字符和 x 个数字的正则表达式匹配字符串
Regex matching string containing at least x characters and x numbers
我需要测试字符串是否符合以下规则:
- 至少有 8 个
[a-zA-Z!@#$%^&+=]
个字符并且至少有 1 个 [0-9]
个数字或
- 至少有 8 个
[0-9]
个数字并且至少有 1 个 [a-zA-Z!@#$%^&+=]
个字符
到目前为止我试过这个:
"^(?=(?=.*[a-zA-Z!@#$%^&+=].*[a-zA-Z!@#$%^&+=].*[a-zA-Z!@#$%^&+=].*[a-zA-Z!@#$%^&+=].*[a-zA-Z!@#$%^&+=].*[a-zA-Z!@#$%^&+=].*[a-zA-Z!@#$%^&+=].*[a-zA-Z!@#$%^&+=])(?=.*[0-9])|(?=.*[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9])(?=.*[a-zA-Z!@#$%^&+=])).{8,}$")
大部分情况下工作正常,但有一种情况失败了:
"!abcdefgh1" --> matched (OK)
"{abcdefgh1" --> matched (NOT OK because character { shouldn't be allowed)
- 如何禁止除
[a-zA-Z!@#$%^&+=]
以外的任何其他字符?
- 是否可以用更短的方式编写该正则表达式?
谢谢
问题是您的 .
匹配 任何字符 。为了保持使用 .
匹配通用字符的便利性,但也要求字符串不包含允许的字符以外的任何字符,一个简单的调整是在字符串的开头进行另一个前瞻,以确保所有字符串末尾之前的字符是 [a-zA-Z!@#$%^&+=]
或 [0-9]
,没有别的。
另请注意,[0-9]
简化为 \d
,这样看起来更好看:
^(?=[a-zA-Z!@#$%^&+=\d]{9,}$) <rest of your regex>
您还可以通过在可能的情况下重复 组中的大字符集来简化您的正则表达式,而不是手动将其写出 8 次。另外,如评论所述,在检查字符串是否有足够的数字时,最好重复 (?:\D*\d)
而不是使用点,因为你知道你希望先行词匹配非数字字符。
其实,因为上面的初始lookahead确保字符串只包含数字和那些特定的非数字字符,而不是在匹配非数字时一次又一次地重复长字符集[a-zA-Z!@#$%^&+=]
,你可以只使用 \D
,因为初始前瞻保证非数字 将 在该字符集中。
例如:
^(?=[a-zA-Z!@#$%^&+=\d]+$)(?:(?=\D*\d)(?=(?:\d*\D){8})|(?=(?:\D*\d){8})(?=\d*\D))
解释:
^(?=[a-zA-Z!@#$%^&+=\d]{9,}$)
- 确保字符串只包含所需的字符(如果没有至少 9 个则立即失败),然后在两者之间交替:
(?=\D*\d)(?=(?:\d*\D){8})
- 字符串包含至少一位数字和 8 个其他字符,或者
(?=(?:\D*\d){8})(?=\d*\D)
- 字符串至少包含 8 个数字,并且至少包含一个其他字符
https://regex101.com/r/18xtBw/2(为了测试,一次只输入一行 - 否则,\D
s 将匹配换行符,这会导致问题)
我需要测试字符串是否符合以下规则:
- 至少有 8 个
[a-zA-Z!@#$%^&+=]
个字符并且至少有 1 个[0-9]
个数字或 - 至少有 8 个
[0-9]
个数字并且至少有 1 个[a-zA-Z!@#$%^&+=]
个字符
到目前为止我试过这个:
"^(?=(?=.*[a-zA-Z!@#$%^&+=].*[a-zA-Z!@#$%^&+=].*[a-zA-Z!@#$%^&+=].*[a-zA-Z!@#$%^&+=].*[a-zA-Z!@#$%^&+=].*[a-zA-Z!@#$%^&+=].*[a-zA-Z!@#$%^&+=].*[a-zA-Z!@#$%^&+=])(?=.*[0-9])|(?=.*[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9])(?=.*[a-zA-Z!@#$%^&+=])).{8,}$")
大部分情况下工作正常,但有一种情况失败了:
"!abcdefgh1" --> matched (OK)
"{abcdefgh1" --> matched (NOT OK because character { shouldn't be allowed)
- 如何禁止除
[a-zA-Z!@#$%^&+=]
以外的任何其他字符? - 是否可以用更短的方式编写该正则表达式?
谢谢
问题是您的 .
匹配 任何字符 。为了保持使用 .
匹配通用字符的便利性,但也要求字符串不包含允许的字符以外的任何字符,一个简单的调整是在字符串的开头进行另一个前瞻,以确保所有字符串末尾之前的字符是 [a-zA-Z!@#$%^&+=]
或 [0-9]
,没有别的。
另请注意,[0-9]
简化为 \d
,这样看起来更好看:
^(?=[a-zA-Z!@#$%^&+=\d]{9,}$) <rest of your regex>
您还可以通过在可能的情况下重复 组中的大字符集来简化您的正则表达式,而不是手动将其写出 8 次。另外,如评论所述,在检查字符串是否有足够的数字时,最好重复 (?:\D*\d)
而不是使用点,因为你知道你希望先行词匹配非数字字符。
其实,因为上面的初始lookahead确保字符串只包含数字和那些特定的非数字字符,而不是在匹配非数字时一次又一次地重复长字符集[a-zA-Z!@#$%^&+=]
,你可以只使用 \D
,因为初始前瞻保证非数字 将 在该字符集中。
例如:
^(?=[a-zA-Z!@#$%^&+=\d]+$)(?:(?=\D*\d)(?=(?:\d*\D){8})|(?=(?:\D*\d){8})(?=\d*\D))
解释:
^(?=[a-zA-Z!@#$%^&+=\d]{9,}$)
- 确保字符串只包含所需的字符(如果没有至少 9 个则立即失败),然后在两者之间交替:
(?=\D*\d)(?=(?:\d*\D){8})
- 字符串包含至少一位数字和 8 个其他字符,或者
(?=(?:\D*\d){8})(?=\d*\D)
- 字符串至少包含 8 个数字,并且至少包含一个其他字符
https://regex101.com/r/18xtBw/2(为了测试,一次只输入一行 - 否则,\D
s 将匹配换行符,这会导致问题)