Я не могу понять, как изменить свое регулярное выражение, чтобы убедиться, что пароль соответствует последнему условию:
{4} В настоящее время он отклоняет пароль, если он состоит из 4 и более цифр, но мне нужно, чтобы он отклонял пароль, состоящий ТОЧНО из 4 цифр.
s1 = 'annII#443'
s2 = 'annII#4343'
s3 = 'annII#43434'
pattern = r"^(?=.*[A-Z]{2,})(?=.*[A-Za-z])(?=.*[0-9])(?!.*[0-9]{4})(?!.*[\s]).*$"
re.findall(pattern, s1) # ['aШnnII#443']
re.findall(pattern, s2) # []
re.findall(pattern, s3) # []
PS: Это просто задача, так что не волнуйтесь. Он не будет использоваться для каких-либо реальных целей.
Вы имеете в виду ^(?=.*[A-Z]{2,})(?=.*[A-Za-z])(?=.*[0-9])(?!.*[0-9]{4})(?!.* ).*$
(обратите внимание на пробел ' '
вместо \s
отредактировал пост. я хочу, чтобы шаблон запрещал только s2, а не s2 и s3 (и другие строки, содержащие 4+ цифры
Я чувствую, что стоит упомянуть, что это ужасные ограничения пароля. С какой стати вы запрещаете пробелы, или 4 цифры подряд, или требуете две заглавные буквы? Абсолютно чокнутые. И почему в год Господа нашего 2022 вы пытаетесь накатить собственное управление паролями?
@JaredSmith - Хотя я согласен с основным мнением (а не с доставкой); было бы полезнее привести примеры хороших ограничений, а не расплывчато критиковать текущие ограничения. Зачем катить свое? Образовательных целях. Отличный способ изучить основные основы.
@ S3DEV Я согласен с вашим мнением и хотел бы дать толчок в лучшем направлении, но, возможно, это слишком большая тема для ТАКОГО ответа, а тем более ТАКОГО комментария. Я думаю, что ссылка на это, вероятно, является хорошим местом для начала ОП.
@sasha - Обычно проверка пароля выполняется в виде ряда правил. Если все правила пройдены, пароль принимается к использованию. Обычно это не делается с помощью одного регулярного выражения.
Чтобы напрямую решить вашу проблему, строки, содержащие 5 чисел подряд, также содержат 4 числа подряд. Если вы хотите, чтобы эта часть регулярного выражения нашла ровно 4 числа без каких-либо других чисел рядом с ними, вам придется сделать что-то вроде этого (?!.*(?<![0-9])[0-9]{4}(?![0-9]))
^
, например. (?!(?:.*\D)?\d{4}(?!\d))
.\D
нецифры перед 4 цифрами и запрещает цифру после.(?=.*[A-Za-z])
выглядит излишним, если вам уже требуется (?=.*[A-Z]{2,})
(2 верхних).{2,}
два и более избыточны. {2}
было бы достаточно и не меняет логику.(?!.*[\s]).*$
вы можете просто использовать \S*$
(верхний соответствует не пробелам)..*?
или даже инвертированный класс, где это возможно.^(?=[^A-Z]*[A-Z]{2})(?=\D*\d)(?!(?:.*\D)?\d{4}(?!\d))\S*$
См. эту демонстрацию на regex101 (добавлено \n
к отрицаниям в многострочной демонстрации, чтобы оставаться в очереди)
так что именно не так?