2010-09-27 4 views
73

Я создаю регулярное выражение для проверки пароля, которое будет использоваться в приложении Java в качестве параметра конфигурации.Regexp Java для проверки пароля

Регулярное выражение является:

^.*(?=.{8,})(?=..*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$ 

Политика паролей:

  • По крайней мере 8 символов

  • Содержит по меньшей мере, одна цифра

  • содержит по меньшей мере один нижний альфа-шар и один верхний альфа-шар

  • содержит по меньшей мере один символ в пределах набора специальных символов (@#%$^ и т.д.)

  • Не содержит пробел, табуляция и т.д.

мне не хватает только пункт 5. Я не могу проверить регулярное выражение для пробела, вкладки, возврата каретки и т. Д.

Может ли кто-нибудь мне помочь?

+0

правила Пароль плохо. Для получения дополнительной информации см. [Справка - Проверка пароля] (https://stackoverflow.com/questions/48345922/reference-password-validation). – ctwheels

ответ

201

Попробуйте это:

^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}$ 

Объяснение:

^     # start-of-string 
(?=.*[0-9])  # a digit must occur at least once 
(?=.*[a-z])  # a lower case letter must occur at least once 
(?=.*[A-Z])  # an upper case letter must occur at least once 
(?=.*[@#$%^&+=]) # a special character must occur at least once 
(?=\S+$)   # no whitespace allowed in the entire string 
.{8,}    # anything, at least eight places though 
$     # end-of-string 

Это легко добавлять, изменять или удалять отдельные правила, поскольку каждое правило является независимым "модуль".

Конструкция (?=.*[xyz]) использует всю строку (.*) и возвращается к первому вступлению, где [xyz] может соответствовать. Это удается, если найдено [xyz], иначе он не работает.

Альтернатива будет использовать неохотный классификатор: (?=.*?[xyz]). Для проверки пароля это вряд ли имеет значение, поскольку гораздо более длинные строки могут быть более эффективным вариантом.

Самый эффективный вариант (но труднее всего читать и поддерживать, следовательно, самый подверженный ошибкам) ​​был бы, конечно, (?=[^xyz]*[xyz]). Для регулярного выражения этой длины и для этой цели я бы рекомендовал делать это таким образом, так как он не имеет реальных преимуществ.

+11

@ Kerby82: В строках Java обратные косые черты должны быть экранированы. Попробуйте использовать '\\ s'. Это требование Java, а не требование регулярного выражения. – Tomalak

+0

yes \ t бессмысленно, так как \ s включает пробельный символ: [\ t \ n \ x0B \ f \ r]. Но обратное сбрасывание \ s теперь в java работает отлично. Большое спасибо! – Kerby82

+0

Вы можете отключить многострочный режим явно как часть регулярного выражения, если вам нужно использовать (? -m: ...) вокруг всего остального –

33

простой пример с использованием регулярных выражений

public class passwordvalidation { 
    public static void main(String[] args) { 
     String passwd = "[email protected]"; 
     String pattern = "(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}"; 
     System.out.println(passwd.matches(pattern)); 
    } 
} 

Пояснения:

  • (?=.*[0-9]) цифра должна происходить, по крайней мере один раз
  • (?=.*[a-z]) строчной буквой должно произойти, по крайней мере один раз
  • (?=.*[A-Z]) верхний буквенное письмо должно происходить не реже одного раза
  • (?=.*[@#$%^&+=]) специальный символ должен произойти, по крайней мере один раз
  • (?=\\S+$) не пробельные разрешено во всей строке
  • .{8,} по крайней мере 8 символов
+3

. {5,10} представляет собой минимум 5 символов и не более 10 символов. На всякий случай кто-то ищет конкретные объяснения. – iabhi

+0

@iabhi, я искал это. Спасибо. –

1

Пароль Требование:

  • Пароль должен быть по крайней мере восемь (8) длиной, где система может ее поддерживать.
  • Пароли должны содержать символы, по меньшей мере, из двух (2) этих группировок: альфа, числовые и специальные символы.

    ^.*(?=.{8,})(?=.*\d)(?=.*[a-zA-Z])|(?=.{8,})(?=.*\d)(?=.*[[email protected]#$%^&])|(?=.{8,})(?=.*[a-zA-Z])(?=.*[[email protected]#$%^&]).*$ 
    

Я проверил его и он работает

0

Я думаю, что это может сделать это также (как более простой режим):

^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])[^\s]{8,}$ 

[Regex Demo]

9

Все ранее приведенные ответы используют ту же (правильную) технику, чтобы использовать отдельный просмотр для каждого требования. Но они содержат пару неэффективности и потенциально массивную ошибку, в зависимости от того, что на самом деле будет использовать пароль.

Начну с регулярным выражением из принятого ответа:

^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}$ 

Прежде всего, так как Java поддерживает \A и \z Я предпочитаю использовать те, чтобы убедиться, что вся строка проверяется, независимо от Pattern.MULTILINE , Это не влияет на производительность, но позволяет избежать ошибок при повторном использовании регулярных выражений.

\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}\z 

Проверка, что пароль не содержит пробелы и проверки его минимальную длину можно сделать за один проход, используя все сразу, помещая переменную квантором {8,} на сокращенном \S, что ограничивает допустимые символы:

\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])\S{8,}\z 

Если предоставленный пароль содержит пробел, все проверки будут выполнены только для того, чтобы окончательная проверка завершилась с ошибкой.Этого можно избежать, заменив все точки с \S:

\A(?=\S*[0-9])(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[@#$%^&+=])\S{8,}\z 

Точка должна использоваться только если вы действительно хотите, чтобы любой символ. В противном случае используйте (отрицаемый) класс символов, чтобы ограничить регулярное выражение только теми символами, которые действительно разрешены. Хотя в этом случае мало что имеет значения, not using the dot when something else is more appropriate - очень хорошая привычка. Я вижу слишком много случаев catastrophic backtracking, потому что разработчику было слишком ленив, чтобы использовать что-то более подходящее, чем точка.

Поскольку есть хороший шанс, первоначальные тесты будут найти соответствующий символ в первой половине пароля, ленивый квантор может быть более эффективным:

\A(?=\S*?[0-9])(?=\S*?[a-z])(?=\S*?[A-Z])(?=\S*?[@#$%^&+=])\S{8,}\z 

Но теперь для действительно важного вопроса: ни один из в ответах упоминается тот факт, что исходный вопрос, похоже, написан кем-то, кто думает в ASCII. Но в Java строки Unicode. В паролях разрешены символы, отличные от ASCII? Если они есть, пробелы только ASCII запрещены или все Unicode-пробелы исключаются.

По умолчанию \s соответствует только пробелу ASCII, поэтому его обратный \S соответствует всем символам Unicode (пробельные символы или нет) и всем символам без пробелов ASCII. Если символы Unicode разрешены, а в Unicode - нет, можно указать флаг UNICODE_CHARACTER_CLASS, чтобы сделать \S исключать пробелы Unicode. Если символы Unicode не разрешены, то [\x21-\x7E] может использоваться вместо \S для соответствия всем символам ASCII, которые не являются пробелом или символом управления.

Это приводит нас к следующей потенциальной проблеме: хотим ли мы разрешать контрольные символы? Первым шагом в написании правильного регулярного выражения является точное указание того, что вы хотите сопоставить, а что нет. Единственный 100% -ный технически правильный ответ заключается в том, что спецификация пароля в вопросе неоднозначна, поскольку она не указывает, разрешены ли определенные диапазоны символов, например, управляющие символы или символы, отличные от ASCII, или нет.

3

Вы не должны использовать чрезмерно сложные Regex (если вы можете избежать их), потому что они

  • трудно прочитать (по крайней мере, для всех, кроме себя)
  • трудно расширить
  • трудно отлаживать

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

Я бы реализовать так:

bool matchesPolicy(pwd) { 
    if (pwd.length < 8) return false; 
    if (not pwd =~ /[0-9]/) return false; 
    if (not pwd =~ /[a-z]/) return false; 
    if (not pwd =~ /[A-Z]/) return false; 
    if (not pwd =~ /[%@$^]/) return false; 
    if (pwd =~ /\s/) return false; 
    return true; 
} 
+0

И с точки зрения безопасности гораздо лучше форсировать более длинные пароли, предотвращать известные пароли (например, 12345 и pass = user), вместо того чтобы делать пароли сложными и трудно запоминающимися. –

0

Для тех, кто заинтересован в минимальных требованиях для каждого типа характера, я бы предложил сделать следующее расширение над принятым ответом Томалака в:

^(?=(.*[0-9]){%d,})(?=(.*[a-z]){%d,})(?=(.*[A-Z]){%d,})(?=(.*[^0-9a-zA-Z]){%d,})(?=\S+$).{%d,}$ 

Обратите внимание, что это строка форматирования, а не окончательный шаблон регулярного выражения. Просто замените% d минимальными требуемыми вхождениями для: цифр, строчных, прописных, нецифровых/символьных и всего пароля (соответственно). Максимальные вхождения маловероятны (если вы не хотите max 0, эффективно отклоняя любые такие символы), но они также могут быть легко добавлены. Обратите внимание на дополнительную группировку вокруг каждого типа, чтобы ограничения min/max допускали несоответствующие совпадения.Это сработало чудеса для системы, в которой мы могли бы централизованно настроить, сколько из каждого типа символов мы требуем, а затем на веб-сайте, а также на двух разных мобильных платформах извлекаем эту информацию, чтобы построить шаблон регулярного выражения на основе указанной выше строки форматирования.

0

легко один

("^ (? =. * [0-9]) (? =. * [AZ]) (? =. * [AZ]) (? =. * [\\ W _]) [\\ S] {8,10} $ ")

  1. (= что-нибудь?) -> означает, что положительный ожидает во всех входной строки и убедитесь, что для этого условие записывается .Sample (=? . * [0-9]) -> означает, что однозначное число записано во всей строке. не указано возвращение false .
  2. (что-нибудь?!) -> (наоборот) означает отрицательный ожидает, если условие написано возвращение ложь.

    близко значение^(условие) (условие) (условие) (условие) [\ S] {8,10} $

+0

Хотя ответы только на код могут дать решение проблемы, некоторые объяснения значительно улучшат качество ответа. –

Смежные вопросы