2017-07-14 82 views
0

工作嘗試其他的變化後,我可以在Java這個正則表達式來驗證密碼:正則表達式特殊字符不能在字符串的開頭在Java

PatternCompiler compiler = new Perl5Compiler(); 
PatternMatcher matcher = new Perl5Matcher(); 
pattern = compiler.compile("^(?=.*?[a-zA-Z])(?![\\\\\\\\_\-])(?=.*?[0-9])([A-Za-z0-9-/-~] 
[^\\\\\\\\_\-]*)$"); 

但它仍然不符合我的測試如預期的情況:

[email protected]比賽
[email protected]不匹配,但它應該匹配
[email protected]不匹配,但它應該匹配
!#ap#2017不匹配,但它應該匹配
[email protected]它不應該匹配
[email protected]它不應該匹配
\[email protected]它不應該匹配

除了三個特殊字符-_\剩下的,都應該匹配在的開始串。

規則:

  • 應該接受所有的特殊字符,除了上述三個符號任意次數。

  • 它必須和應該包含一個數字和大寫字母在字符串中的任何位置。

+0

好吧,請嘗試['^(?=。*?[a-zA-Z])(?=。*?[0-9])[^ \\\\ _-] * $'](https://regex101.com/r/cmut9v/3)。請提供問題中的規則。 –

+0

您能否通過在字符串的開頭加入特殊字符來表達與我的相同的表達方式?整個表達式的改變並不是在生產環境中的良好做法 – Kiran

+0

用'(?:[A-Za-z0-9 -/- 〜] | []替換'[A-Za-z0-9 -/- 〜]^\\ w \\\\ - ])'然後。但''[^ \\\\\ _ _ - - ]'看起來太複雜了,它一定是'[^ \\\\ _-]'。請注意,'/ - 〜'匹配的不只是3個符號,因爲它是從'/'到'〜'的*範圍。 –

回答

0

你似乎需要

"^(?=[^a-zA-Z]*[a-zA-Z])(?=[^0-9]*[0-9])[^\\\\_-]*$" 

regex demo

  • ^ - 串
  • (?=[^a-zA-Z]*[a-zA-Z])的開始 - 一個積極的前瞻,需要至少1 ASCII字母([a-zA-Z])在除字母之外的0+字符後出現([^a-zA-Z]*
  • (?=[^0-9]*[0-9]) - 至少1個ASCII數字(同樣principle of contrast如上這裏使用)
  • [^\\\\_-]* - 0+字符以外\(Java字符串文字內,\應加倍來表示1個反斜槓,並以匹配用正則表達式一個反斜槓,我們需要雙反斜線),_-
  • $ - 字符串的結尾(\\z可能會更好,雖然它在字符串的非常末相匹配)。
1

你有兩條規則,爲什麼不創建多個正則表達式?

除了上面三個符號以外,它應該接受所有特殊字符的任意次數。

對於這一塊,確保它匹配[-\\_](注意:-是在字符類中的第一個字符,否則會被解釋爲範圍。

它必須和應該包含一個數字和大寫字母在字符串中的任何地方。

對於這一塊,確保它匹配[A-Z][0-9]

爲了便於修改和擴展,做一些抽象:

class PasswordRule 
{ 
    private Pattern pattern; 
    // If true, string must match, if false string must not match 
    private boolean shouldMatch; 

    PasswordRule(String patternString, boolean shouldMatch) 
    { 
     this.shouldMatch = shouldMatch; 
     this.pattern = compiler.compile(patternString); 
    } 

    boolean match(String passwordString) 
    { 
     return pattern.matches(passwordString) == shouldMatch; 
    } 
} 

我不知道或不關心,如果我有API爲Perl5在上述匹配正確的,但你應該明白我的意思。那麼你的規則陣列中的

PasswordRule rules[] = 
{ 
    PasswordRule("[-\\\\_]", false), 
    PasswordRule("[A-Z]", true), 
    PasswordRule("[0-9]", true) 
}; 

boolean passwordIsOk(String password) 
{ 
    for (PasswordRule rule : rules) 
    { 
     if (!rule.match(password) 
     { 
      return false; 
     } 
    } 
    return true; 
} 

使用上面去,你的規則比一個可怕的正則表達式更爲靈活和修改。

0

下面是一種替代解決方案 - 反轉條件。這個表達式

^(?:[^0-9]*|[^A-Z]*|[_\\-].*)$ 

比賽符合密碼。這使得它更容易理解。

它匹配任何

  • 字符串無位數
  • 字符串無大寫字母
  • 包含任意_\-

See it illustrated here at regex101的字符串。

雖然在您的問題中仍然存在一些不清楚的問題,因此可能需要進行調整。 (限制起始字符我作爲評論提到)