RegEx, чтобы убедиться, что строка содержит хотя бы один символ нижнего регистра, символ верхнего регистра, цифру и символ

156

Что такое регулярное выражение, чтобы убедиться, что данная строка содержит хотя бы один символ из каждой из следующих категорий.

  • Строчные буквы
  • Прописная буква
  • цифра
  • Условное обозначение

Я знаю , что шаблоны для отдельных наборов , а именно [a-z], [A-Z], \dи _|[^\w](я получил их исправить, не так ли?).

Но как мне объединить их, чтобы убедиться, что строка содержит все это в любом порядке?

Amarghosh
источник
Какая платформа / регулярное выражение? Ответ Барта верен, но прогнозные утверждения ненадежны, например, в JavaScript.
bobince
Нигде конкретно - я учу регулярные выражения. Есть ли альтернатива, которая может быть использована в JavaScript?
Амаргош
@bobince Эй, я пытаюсь выяснить, почему прогнозные утверждения не надежны в Javascript. Есть ли рецензия на это?
Крис Бир
@ChrisB: действительно запутанная ошибка IE / JScript: blog.stevenlevithan.com/archives/regex-lookahead-bug
bobince

Ответы:

349

Если вам нужно одно регулярное выражение, попробуйте:

(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*\W)

Краткое объяснение:

(?=.*[a-z])        // use positive look ahead to see if at least one lower case letter exists
(?=.*[A-Z])        // use positive look ahead to see if at least one upper case letter exists
(?=.*\d)           // use positive look ahead to see if at least one digit exists
(?=.*\W])        // use positive look ahead to see if at least one non-word character exists

И я согласен с SilentGhost, \Wможет быть немного шире. Я бы заменил его набором символов следующим образом: [-+_!@#$%^&*.,?](не стесняйтесь добавлять больше, конечно!)

Барт Киерс
источник
Что будет, если я поменяю последний .+на .*? Я не смог придумать тестовый пример, который не удался .*. Они одинаковы в этом контексте? «Ноль или более символов», кажется, хорошо - просто ищет подтверждения.
Амаргош
@ Amarghosh: в этом случае это не имеет значения. Из-за позитивных ожиданий строка уже содержит не менее 4 символов. Так что это не имеет никакого значения для изменения .+в .*или даже .{4,}по этому вопросу.
Барт Киерс
Если вы захотите добавить небольшое объяснение, у меня возникли проблемы с пониманием того, как комбинация этих подсказок гарантирует, что будет присутствовать хотя бы 1 из каждого набора символов
Sharlike
@Sharlike, я не знаю, как перефразировать его, чтобы было легче понять. Особенно в этих маленьких комментариях. Я рекомендую вам прочитать это: normal-expressions.info/lookaround.html, и если у вас все еще есть вопросы, просто оставьте свой вопрос. Удачи!
Барт Киерс
4
@ikertxu, попробуйте что-то вроде этого:^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?!.*[&%$]).{6,}$
Барт Киерс
20

Барт Киерс, у твоего регулярного выражения есть пара проблем. Лучший способ сделать это это:

(.*[a-z].*)       // For lower cases
(.*[A-Z].*)       // For upper cases
(.*\d.*)          // For digits

Таким образом, вы ищете независимо от того, в начале, в конце или в середине. У тебя много проблем со сложными паролями.

Хуан Фураттини
источник
5
Вы не проверяете символы в соответствии с запросом OP.
Казимир
5

Вы можете сопоставить эти три группы отдельно и убедиться, что все они присутствуют. Кроме того, это [^\w]кажется слишком широким, но если это то, что вы хотите, вы можете заменить его \W.

SilentGhost
источник
Спасибо. Я не знал о \ W. Просто посмотрел, чтобы найти, что это соответствует не Word. Есть ли разница между \ W и [\ W]? Является ли [\ W] просто избыточным?
Амаргош
@ Amarghosh, да, \Wи [\W]результат тот же.
Барт Киерс