2012-05-11 53 views
0

我正在使用以下正則表達式。 (?=。+ [az])(?=。+ [AZ])(?=。+ [^ a-zA-Z])。{8,}正則表達式不能按預期工作

我的目標是有一個密碼具有低於

大寫字符的4個屬性的3,小寫字符,數字,特殊字符

我使用http://rubular.com/r/i26nwsTcaUhttp://regexlib.com/RETester.aspx測試使用以下輸入表達

[email protected] 
password1P 
Password1 
paSSw0rd 

所有的這些應該通過,但只有第二和第四通過http://rubular.com/r/i26nwsTcaU,全部通過http://regexlib.com/RETester.aspx

我也有下面的代碼,我使用驗證

private void doValidate(String inputStr,String regex) { 
    Pattern pattern = Pattern.compile(regex); 
    if(!pattern.matcher(inputStr).matches()){ 
     String errMessage = ""; 
     throw new UniquenessConstraintViolatedException(errMessage); 
    } 
} 

這個代碼將無法通過驗證「密碼1」,它應該通過。 儘可能的去表達我的理解是這樣的

must have lower (?=.+[a-z]) 
must have upper (?=.+[A-Z]) 
must have non alpha (?=.+[^a-zA-Z]) 
must be eight characters long .{8,} 

誰能告訴我它是什麼,我做錯了。

在此先感謝。

+0

http://xkcd.com/936/ – FlyingStreudel

+0

@Vulcan但或將意味着它會匹配所有這些。 – Cfreak

+0

問題是您的首字母大寫被忽略。如果您在字符串的其他任何位置添加大寫字母,則對於密碼1和3可以正常工作。 – Vulcan

回答

1

從本質上講,.+子表達式是罪魁禍首,他們應該是.*。否則,lookahead部分查找小寫,大寫或非alpha,但每個相應類型的字符不會計算它是否是字符串中的第一個字符。因此,您不是驗證密碼,而是驗證第一個字符被截斷的密碼。雖然@Cfreak不正確,但他很接近 - 用正常的正則表達式來做你的工作是不可能的,你必須使用他的建議。使用lookahead組 - (?=) - 可以執行您所需的操作。儘管如此,我個人更願意像@Cfreak所說的那樣對它進行編碼 - 它更具可讀性,並且您的意圖在代碼中更加清晰。複雜的正則表達式往往很難寫,但在一段時間後幾乎不可能讀取,調試或改進。

+0

感謝大家的快速回復。 *解決了我的問題。我使用正則表達式爲密碼外部化規則的原因,以便以後可以在不重新部署應用程序的情況下進行更改。再次感謝所有答覆。 – peekay

0

你的正則表達式,現在說,你必須有1個或多個小寫字符,後跟1個或多個大寫字母后跟1個或多個大寫或小寫字符,其次是8個或更多字符。

正則表達式不能做,除非你指定一個特定的人物出現。你基本上需要將你的正則表達式的每個部分分成它自己的正則表達式並檢查每一部分。你可以使用任何字符串長度方法Java來檢查長度(對不起,我不是一個Java開發人員,所以我不知道它是什麼離開我的頭)。

僞代碼:

if(regexForLower && regexForUpper && regexForSpecial && string.length == 8) { 
    // pass 
} 
+0

不一定。我現在有一個模式,只接受第一個模式,但那是因爲@符號。 – Vulcan

0

正如我在評論說,位置0大寫字母被忽略。

以下是所有四個密碼匹配的正則表達式。

(?=.+\\d)(?=.+[a-z])(?=\\w*[A-Z]).{8,} 
0

我不會使用這樣的正則表達式。

  • 很難理解
  • 難以調試
  • 很難擴展
  • 你不能做與它的結果

如果你想告訴客戶什麼是密碼錯誤,您再次調查密碼。在真實世界的環境中,您可能需要支持來自國外語言環境的字符。

import java.util.*; 
/** 
    Pwtest 

    @author Stefan Wagner 
    @date Fr 11. Mai 20:55:38 CEST 2012 
*/ 
public class Pwtest 
{ 

    public int boolcount (boolean [] arr) { 
     int sum = 0; 
     for (boolean b : arr) 
      if (b) 
       ++sum; 
     return sum; 
    } 

    public boolean [] rulesMatch (String [] groups, String password) { 
     int idx = 0; 
     boolean [] matches = new boolean [groups.length]; 
     for (String g: groups) { 
      matches[idx] = (password.matches (".*" + g + ".*")); 
      ++idx; 
     } 
     return matches;  
    } 

    public Pwtest() 
    { 
     String [] groups = new String [] {"[a-z]", "[A-Z]", "[0-9]", "[^a-zA-Z0-9]"}; 
     String [] pwl = new String [] {"[email protected]", "password1P", "Password1", "paSSw0rd", "onlylower", "ONLYUPPER", "1234", ",:?!"}; 
     List <boolean[]> lii = new ArrayList <boolean[]>(); 
     for (String password: pwl) { 
      lii.add (rulesMatch (groups, password)); 
     } 

     for (int i = 0 ; i < lii.size(); ++i) { 
      boolean [] matches = lii.get (i); 
      String pw = pwl[i]; 
      if (boolcount (matches) < 3) { 
       System.out.print ("Password:\t" + pw + " violates rule (s): "); 
       int idx = 0; 
       for (boolean b: matches) { 
        if (! b) 
         System.out.print (groups[idx] + " "); 
        ++idx; 
       } 
       System.out.println(); 
      } 
      else System.out.println ("Password:\t" + pw + " fine "); 
     } 
    } 

    public static void main (String args[]) 
    { 
     new Pwtest(); 
    } 
} 

輸出:

Password: [email protected] fine 
Password: password1P fine 
Password: Password1 fine 
Password: paSSw0rd fine 
Password: onlylower violates rule (s): [A-Z] [0-9] [^a-zA-Z0-9] 
Password: ONLYUPPER violates rule (s): [a-z] [0-9] [^a-zA-Z0-9] 
Password: 1234 violates rule (s): [a-z] [A-Z] [^a-zA-Z0-9] 
Password: ,:?! violates rule (s): [a-z] [A-Z] [0-9] 
Password: Übergrößen345 fine 
Password: 345ÄÜö violates rule (s): [a-z] [A-Z] 
相關問題