Соответствующая регулярному выражению строка, содержащая не менее x символов и x чисел - PullRequest
0 голосов
/ 20 сентября 2018

У меня есть требование проверить, соответствует ли строка следующим правилам:

  • Имеет не менее 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)
  1. Как запретить любые другие символы, кроме [a-zA-Z!@#$%^&+=]?
  2. Можно ли написать это регулярное выражение более коротким способом?

Спасибо

1 Ответ

0 голосов
/ 20 сентября 2018

Проблема в том, что ваши . 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 будет соответствовать символам новой строки, что вызовет проблемы)

...