2013-03-13 2 views
5

Я пытаюсь создать регулярное выражение для соответствия шаблону (для паролей), где строка должна быть от 8 до 30 символов, должна иметь не менее 2 символов цифр, не менее 2 букв (без учета регистра), не менее 1 специального символа и пробелов.Regex, чтобы соответствовать как минимум 2 цифрам, 2 буквам в любом порядке в строке

У меня есть пробелы и специальные символы, соответствующие работе, но меня бросают на 2 цифры и 2 буквы, потому что они не обязательно должны быть последовательными.

i.e должно соответствовать a1b2c$ или ab12$ или 1aab2c$.

Что-то вроде этого для букв?

(?=.*[a-zA-Z].*[a-zA-Z]) // Not sure. 

Эта строка ниже работает, но только если 2 буквы подряд и 2 номера consecutive..it терпит неудачу, если буквы, цифры, специальные символы переплетены.

(?=^.{8,30}$)((?=.*\\d)(?=.*[A-Za-z]{2})(?=.*[0-9]{2})(?=.*[[email protected]#$%^&*?]{1})(?!.*[\\s]))^.* 
+5

Вы абсолютно уверены, что вам нужно регулярное выражение для этого? – Scorpil

+0

Я бы возражал против регулярного выражения и просто имел индивидуальные проверки для каждого из них с операторами if и некоторой функцией string.contains(). gparyani дал решение, которое выглядит намного лучше, чем регулярное выражение. – user1751547

+0

Похоже, мне нужно регулярное выражение, так как это часть конфигурации Liferay. – user2166893

ответ

5

Если вы не хотите, чтобы письма были последовательными (?=.*[a-zA-Z].*[a-zA-Z]) - правильный подход. То же самое относится к цифрам (?=.*\\d.*\\d) или (?=(.*\\d){2}).

Попробуйте это регулярное выражение

(?=^.{8,30}$)(?=(.*\\d){2})(?=(.*[A-Za-z]){2})(?=.*[[email protected]#$%^&*?])(?!.*[\\s])^.* 
+1

Спасибо. Это работает! Именно то, что я искал. – user2166893

+0

Рад, что я мог бы помочь :) – Pshemo

0

я наблюдать ваши примеры, которые вы предоставляете не 8 до 30 символов

попробовать этот шаблон один раз, если вы хотите 8-30 символов

(?=[^\s]*[^\sa-zA-Z0-9][^\s]*)(?=[^\s]*[a-zA-Z][^\s]*[A-Za-z][^\s]*)(?=[^\s]*\d[^\s]*\d[^\s]*)[^\s]{8,30} 
1

Ваше предположение было бы довольно точно. Это можно сделать немного более элегантным с парнерами.

(?=(.*[a-zA-Z]){2}) 

Звучит так, как будто вы на правильном пути.

3

Используйте цикл для обхода строки:

/** 
* Checks to see if the specified string has between 8 and 30 characters, has at least 2 digits, at least 2 letters, at least one special character, and no spaces. 
* @param s the String to be checked 
* @return s, if it passes the above test 
* @throws IllegalArgumentException if it does not 
*/ 
public static String check(String s) 
{ 
    IllegalArgumentException invalid = new IllegalArgumentException(); 
    if(s.length() < 8 || s.length() > 30) 
     throw invalid; 
    int letters = 0, numbers = 0, specialChars = 0; 
    for(char c : s.toCharArray()) 
    { 
     if(c == ' ') 
      throw invalid; 
     else if(Character.isLetter(c)) 
      ++letters; 
     else if(Character.isDigit(c)) 
      ++numbers; 
     else 
      ++specialChars; 

    } 
    if(letters < 2 || numbers < 2 || specialChars < 1) 
     throw invalid; 
    return s; 
} 
+0

Использование регулярного выражения намного эффективнее – Barnaby