至少包含 x 个字符和 x 个数字的正则表达式匹配字符串

Regex matching string containing at least x characters and x numbers

我需要测试字符串是否符合以下规则:

到目前为止我试过这个:

"^(?=(?=.*[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)
  1. 如何禁止除 [a-zA-Z!@#$%^&+=] 以外的任何其他字符?
  2. 是否可以用更短的方式编写该正则表达式?

谢谢

问题是您的 . 匹配 任何字符 。为了保持使用 . 匹配通用字符的便利性,但也要求字符串不包含允许的字符以外的任何字符,一个简单的调整是在字符串的开头进行另一个前瞻,以确保所有字符串末尾之前的字符是 [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(为了测试,一次只输入一行 - 否则,\Ds 将匹配换行符,这会导致问题)