Проблема в том, что ваши .
s соответствуют любому символу .Чтобы сохранить удобство использования .
для сопоставления с универсальным символом, а также требовать, чтобы строка не содержала никаких символов, кроме того, что разрешено, простой твик будет еще одним средством просмотра в начале строки, чтобы гарантировать, что все символы передконец строки - [a-zA-Z!@#$%^&+=]
или [0-9]
, ничего больше.
Также обратите внимание, что [0-9]
упрощается до \d
, что немного лучше:
^(?=[a-zA-Z!@#$%^&+=\d]{9,}$) <rest of your regex>
Вы также можете упростить свое регулярное выражение, повторяя большой набор символов в группе, когда это возможно, вместо того, чтобы записывать его вручную 8 раз.Кроме того, как отмечается в комментарии, при проверке наличия в строке достаточного количества цифр лучше повторить (?:\D*\d)
, а не использовать точку, поскольку вы знаете, что хотите, чтобы антецедент совпадал с нецифровыми символами.
На самом деле,потому что начальный просмотр выше гарантирует, что строка содержит только цифры и те определенные нецифровые символы, вместо того, чтобы повторять длинный и повторяющийся набор символов [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 (для проверки введите oтолько по одной строке за раз - в противном случае \D
s будет соответствовать символам новой строки, что вызовет проблемы)