2013-05-13 6 views
0

Я искал сайт и не нашел точно, что я ищу. Критерии Пароль:Regex для ввода пароля

  1. Должно быть 6 символов, 50 макс
  2. должна включать в себя 1 альфа-символ
  3. должны включать в себя 1 цифровой или специальный символ

Вот что я имею в Java:

public static Pattern p = Pattern.compile(
"((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])|(?=.*[\\[email protected]#$%^&*\\(\\)_+\\{\\}\\[\\]\\?<>|_]).{6,50})" 
); 

Проблема в том, что пароль 1234567 соответствует (это действительно), который так не должно быть.

Любая помощь будет отличной.

+5

Я бы никогда не использовал RegEx для проверки пароля. Лучше и быстрее проверить его вручную. –

+4

Создайте по 3 регулярных выражения для каждого случая и проверите все вместе с помощью операции И. –

+4

Возможно, вы захотите разбить требования. Особенно, если вы планируете информировать пользователя о том, почему их пароль не соответствует требованиям. Если вы поместите все это в одно утверждение, вы не можете сказать, какое требование было неудовлетворенным, и не может сказать им конкретную причину. – BLuFeNiX

ответ

0

Убедитесь, что вы используете Matcher.matches() метод, утверждать, что вся строка соответствует шаблону.

Ваше текущее регулярное выражение:

"((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])|(?=.*[\\[email protected]#$%^&*\\(\\)_+\\{\\}\\[\\]\\?<>|_]).{6,50})" 

означает:

  • Строка должна содержать, по крайней мере цифры (?=.*\\d), а нижний регистр букв английского алфавита (?=.*[a-z]) и символ верхнего регистра (?=.*[A-Z])
  • ИЛИ | Строка должна содержать не менее 1 символа, которая может быть цифрой или специальным символом (?=.*[\\[email protected]#$%^&*\\(\\)_+\\{\\}\\[\\]\\?<>|_])
  • Любое условие выше имеет значение true, а строка должна иметь длину от 6 до 50 символов и не содержать разделителя строк.

Правильное регулярное выражение:

"(?=.*[a-zA-Z])(?=.*[\\[email protected]#$%^&*()_+{}\\[\\]?<>|]).{6,50}" 

Это будет проверять:

  • Строка должна содержать знак алфавита английского (либо в верхнем регистре или нижнем регистре) (?=.*[a-zA-Z]), и характер, может быть либо цифрой, либо специальным символом (?=.*[\\[email protected]#$%^&*()_+{}\\[\\]?<>|])
  • Строка должна быть от 6 до 50 символов и не содержать строк Parator.

Обратите внимание, что я удалил ускользающее для большинства персонажей, за исключением [], поскольку {}?() теряет свое особое значение внутри класса символов.

5

Я бы не стал использовать одно регулярное выражение для этого. Регулярные выражения, как правило, не работают хорошо, когда они становятся длинными и сложными.

boolean valid(String password){ 
    return password != null && 
    password.length() >= 6 && 
    password.length() <= 50 && 
    password.matches(".*[A-Za-z].*") && 
    password.matches(".*[0-9\\~\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)_+\\{\\}\\[\\]\\?<>|_].*"); 
} 
+0

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

0

Я хотел бы предложить разделение на отдельные регулярные выражения

$re_numbers = "/[0-9]/"; 
$re_letters = "/[a-zA-Z]/"; 

оба они должны соответствовать и длина испытывается отдельно, тоже. Код выглядит довольно чистым, и его легче понять/изменить.

+0

Вопрос о Java regex. Однако идея прекрасна. – nhahtdh

0

Это слишком сложно для такой простой задачи:

длина Validate с помощью строки # длина()

password.length() >= 6 && password.length() <= 50 

Validate каждая группа с помощью Сличитель # находку()

Pattern alpha = Pattern.compile("[a-zA-Z]"); 
boolean hasAlpha = alpha.matcher(password).find(); 
Pattern digit = Pattern.compile("\d"); 
boolean hasDigit = digit.matcher(password).find(); 
Pattern special = Pattern.compile("[\\~\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)_+\\{\\}\\[\\]\\?<>|_]"); 
boolean hasSpecial = special.matcher(password).find(); 
1

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

+0

Вы вводите в заблуждение теоретическое регулярное выражение и «регулярное выражение», которое используется в языках программирования. «Регулярное выражение» в Java/.NET/PHP не является точно регулярным выражением в теоретическом смысле, поэтому они намного мощнее теоретического регулярного выражения. – nhahtdh

+0

Единственное значимое дополнение - это откат, который не позволяет использовать полные контекстные языки, о которых я думаю, и почти наверняка не преодолеет эту проблему. – Joel

+0

Java regex не разрешает полный контекстно-свободный язык, но регулярное выражение .NET и регулярное выражение PHP могут корректно выполнять скобки. – nhahtdh

1

Я хотел бы предложить вам, чтобы отделить символы и проверки длины:

boolean checkPassword(String password) { 
    return password.length() >= 6 && password.length() <= 50 && Pattern.compile("\\d|\\w").matcher(password).find(); 
} 
Смежные вопросы