2013-01-17 57 views
0

任何人都可以請解釋下面的正則表達式,這在我加入之前已經在我的應用程序中使用了很長時間了,我對正則表達式很新。解釋Regex提到

/^.*(?=.{6,10})(?=.*[a-zA-Z].*[a-zA-Z].*[a-zA-Z].*[a-zA-Z])(?=.*\d.*\d).*$/ 

據我瞭解

這個表達式將驗證 - 最少6個字符至最多10個字符 - 將難逃像字符^和$

也,我的基本需求是我想要一個至少6個字符的正則表達式,其中1個字符是一個數字,另一個是特殊字符。

+3

理解正則表達式非常重要。一旦你這樣做,通過'http:// www.txt2re.com /' – Chris

+0

[Regular-Expressions.info - 正則表達式教程](http://www.regular-expressions.info/) – Tim

+0

'^'和'$'是錨。要在RegEx中轉義某些內容,請使用'\'。 – Tim

回答

7
^.*(?=.{6,10})(?=.*[a-zA-Z].*[a-zA-Z].*[a-zA-Z].*[a-zA-Z])(?=.*\d.*\d).*$ 
  • ^被稱爲「錨」。它基本上意味着任何以下文本必須在「輸入開始」之後立即生效。所以^B會匹配「B」而不是「AB」,因爲在第二個「B」不是第一個字符。

  • .*匹配0個或多個字符 - 除換行符外的任何字符(默認情況下)。這就是所謂的貪婪量詞 - 正則表達式引擎會將所有字符匹配(「消耗」)到輸入末尾(或行尾),然後向後反向處理其餘表達式(它是「只有當它必須放棄「字符)。在一個正則表達式中,一旦一個字符「匹配」,表達式的其他部分就不能再匹配它(除了零寬度外圍,下一個)。

  • (?=.{6,10})是一個向前看的錨點,它與輸入中的位置匹配。它會在輸入中找到一個有6到10個字符的位置,但它不會「消耗」這些字符,這意味着以下表達式可以自由匹配它們。

  • (?=.*[a-zA-Z].*[a-zA-Z].*[a-zA-Z].*[a-zA-Z])是另一個前視錨。它與輸入中的位置匹配,其中以下文本包含四個字母([a-zA-Z]匹配一個小寫字母或大寫字母),但任意數量的其他字符(包括零字符)可能位於它們之間。例如:「++ a5b --- C @ D」會匹配。再次,作爲一個錨點,它實際上不會「消耗」匹配的字符 - 它只能在文本中找到與表達式匹配的位置。

  • (?=.*\d.*\d)另一個向前看。這匹配兩個數字後跟的位置(以及其間任意數量的其他字符)。

  • .*已經覆蓋這個。

  • $這是另一種匹配輸入結尾(或行末尾 - 換行符之前的位置)的錨點。它表示前面的表達式必須匹配字符串末尾的字符。當^$一起使用時,這意味着整個輸入必須匹配(而不僅僅是它的一部分)。所以/bcd/會匹配「abcde」,但/^bcd$/不匹配「abcde」,因爲匹配中不能包含「a」和「e」。

注意

這看起來像一個密碼驗證正則表達式。如果是,請注意它已損壞。開頭和結尾的.*將允許密碼長度超過10個字符。它也可以被重寫成稍短一些。我相信,以下將是一個可以接受(稍微更具可讀性)替代:

^(?=(.*[a-zA-Z]){4})(?=(.*\d){2}).{6,10}$ 

感謝@nhahtdh您指出實現字符長度限制的正確方法。

+2

正則表達式的很好的解釋。來自OP的現有正則表達式看起來像一個密碼驗證正則表達式,用於執行一定的複雜性。從它的外觀來看,它需要6到10個字符,必須包含至少4個字母和至少2個數字。 – Erik

+0

優秀的解釋。如果可以的話,我會給你更多的讚揚。 – Tim

+0

第一個'。*'是完全多餘的。我認爲如果你在正則表達式中添加SiLo的高級視圖會更好一些。 (他關掉的一件事是正則表達式可以匹配min = 6和max = inf。字符)。 – nhahtdh

0

REGEXPLANATION

  • /.../:斜線經常用來表示其中的正則表達式定義

  • ^面積:匹配開始輸入字符串的

  • .:這可以匹配任何字符

  • *:匹配以前的符號0或多次

  • .{6,10}.(任何字符)匹配某處6和10倍之間

  • [a-zA-Z]az之間和A之間和所有字符匹配Z

  • \d:一個數字相匹配。

  • $:匹配輸入結束。

我覺得只是做它在正則表達式所有的符號,你已經發布

+1

'?='是積極的預測,沒有捕獲的分組是'?:'。 – speakr

2

檢查Cyborgx37的語法解釋的答案。我將對正則表達式的含義做一些解釋。

^.*(?=.{6,10})(?=.*[a-zA-Z].*[a-zA-Z].*[a-zA-Z].*[a-zA-Z])(?=.*\d.*\d).*$ 

第一.*是多餘的,因爲其餘的都是零寬度斷言以任何字符..*開始,並且在端部。

正則表達式匹配的最小6個字符,由於斷言(?=.{6,10})。但是,正則表達式可匹配的字符串的字符數沒有上限。這是因爲末尾的.*(前面的.*也有貢獻)。

(?=.*[a-zA-Z].*[a-zA-Z].*[a-zA-Z].*[a-zA-Z])這部分斷言有至少4個英文字母的字符(大寫或小寫)。並且(?=.*\d.*\d)聲稱至少有2位數字(0-9)。由於[a-zA-Z]\d是不相交的集合,因此組合這兩個條件使得冗餘是(?=.{6,10})

.*[a-zA-Z].*[a-zA-Z].*[a-zA-Z].*[a-zA-Z]語法也是不必要的冗長。使用重複可以縮短:(?:.*[a-zA-Z]){4}

下面的正則表達式相當於原來的正則表達式。可是,我真的懷疑你的當前和你的正則表達式這相當於重寫你想要做什麼:

^(?=(?:.*[a-zA-Z]){4})(?=(?:.*\d){2}).*$ 

的長度更明確,因爲清晰度越好。含義保持相同:

^(?=(?:.*[a-zA-Z]){4})(?=(?:.*\d){2}).{6,}$ 

回顧

  • 最小長度= 6
  • 上最大長度
  • 至少4英語字母表,小寫無限制或大寫
  • 在至少2位0-9
+0

第一個'。*'實際上並不是多餘的。它對正則表達式有顯着的影響,因爲它抵消了'(?=。{6,10})'上的最大邊界。我已經更新了我的答案來解決這個問題。 +1爲更可讀的'。{6,}',即使它不能強制顯示所期望的(儘管錯誤的)上限限制。 – JDB

+0

@ Cyborgx37:無論如何,最大邊界都被最後一個'。*'否定。畢竟這是匹配從開始到結束'^ $'。 '。*'是多餘的,至少在這種情況下。如果'。{6,10}'後面有'$',那麼故事將會不同,然後'。*'確實否定了最大範圍。 – nhahtdh

+0

Duh。我現在感覺有點傻。 – JDB

0

對於您正則表達式的要求,這裏是你會用什麼:

^(?=.{6,}$)(?=.*?\d)(?=.*?[[email protected]#$%&*()+_=?\^-]).* 

這裏,它被展開爲您:

^   // Anchor the beginning of the string (password). 

(?=.{6,}$) // Look ahead: Six or more characters, then the end of the string. 

(?=.*?\d) // Look ahead: Anything, then a single digit. 

(?=.*?[[email protected]#$%&*()+_=?\^-]) // Look ahead: Anything, and a special character. 

.*   // Passes our look aheads, let's consume the entire string. 

正如你所看到的,特殊字符必須被明確定義因爲它們沒有預留的簡寫符號(如\w,\s,\d)。這裏是公認的人(你可以修改你的願望):

!, @, #, $, %, ^, &, *, (,), -, +, _, =, ?

理解的關鍵正則表達式看aheads是要記住,他們不會移動解析器的位置。這意味着(?=...)將開始查看最後一次模式匹配後的第一個字符,隨後的(?=...)將向前看。

+1

角色類中有太多不必要的轉義。 ''[!@#$%&*()+ _ =?\^- ]' – nhahtdh

+0

哦,我認爲這是必要的,但我想''裏面不是。謝謝! – Erik