2013-08-27 57 views
2

給出一個字符串一些指針,它必須具備以下條件:需要一些正則表達式驗證

  1. 只有一個號碼
  2. 在(@#$ *)
  3. 6個套管字母只有一個特殊字符

該字符串可以是上述條件的任意組合,且長度必須爲8。

例子:

  1. 2 @ QWERTY
  2. 1asddfg

  3. QWE * yt2u
  4. qw2wqia

這裏我正則表達式到目前爲止:

!/^(?=.*[0-9])(?=.*[^a-z])(?=.*[a-z])(?=.*[@#$*])\S{8,}$/.test(string) 

它適用於上述情況,但休息案件象下面這樣:

  1. 2 @ 2qwert
  2. 2 @@ QWERT

我缺少什麼?

+1

爲什麼不把它分成4個簡單的正則表達式,並要求它們都匹配?至少會更容易實施和閱讀。 – alecxe

+0

爲什麼使用正則表達式?沒有任何意義。 –

+0

「下面的案例會打破」:他們應該通過還是失敗?失敗,我假設。你的模式中沒有需要6個字母的東西,那爲什麼要拒​​絕?另外,你的第一個和第四個lookahead確保第二個將總是*通過,所以它是多餘的。 –

回答

2

說明

你的表情符,因爲:

^(?=.*[0-9])(?=.*[^a-z])(?=.*[a-z])(?=.*[@#$*])\S{8,}$ 
      ^^^^^^^^^^^^      ^^^^^^ 
  • [^a-z]是一個否定的字符類,所以這將匹配任何這是不a-z。我不確定這部分表達的目的是什麼。
  • \S將匹配任何非空白字符。這是允許字母,數字,unicode字符,新行字符,任何符號等。
  • {8,}將允許8個或更多的前面的字符。這允許一個字符串是無限的長度。在你的帖子中,你希望字符串最多爲8個字符。
  • 也作爲一種最佳做法,您應該始終跳過#,因爲它可以用作某些正則表達式版本中的註釋字符,因此表達式已準備好以防萬一使用x選項。

我會修改你的表情是這樣的:

  • 要求字符串有1號
  • 要求字符串有1個@#$*符號
  • 要求字符串有6 a-z小寫字母(請勿使用不區分大小寫的選項)
  • 要求字符串的總長度爲8個字符

^(?=.*?[0-9])(?=.*?[@\#$*])(?=(?:.*?[a-z]){6}).{8}$

Live Demo

enter image description here

NODE      EXPLANATION 
-------------------------------------------------------------------------------- 
^      the beginning of the string 
-------------------------------------------------------------------------------- 
    (?=      look ahead to see if there is: 
-------------------------------------------------------------------------------- 
    .*?      any character except \n (0 or more times 
          (matching the least amount possible)) 
-------------------------------------------------------------------------------- 
    [0-9]     any character of: '0' to '9' 
-------------------------------------------------------------------------------- 
)      end of look-ahead 
-------------------------------------------------------------------------------- 
    (?=      look ahead to see if there is: 
-------------------------------------------------------------------------------- 
    .*?      any character except \n (0 or more times 
          (matching the least amount possible)) 
-------------------------------------------------------------------------------- 
    [@\#$*]     any character of: '@', '\#', '$', '*' 
-------------------------------------------------------------------------------- 
)      end of look-ahead 
-------------------------------------------------------------------------------- 
    (?=      look ahead to see if there is: 
-------------------------------------------------------------------------------- 
    (?:      group, but do not capture (6 times): 
-------------------------------------------------------------------------------- 
     .*?      any character except \n (0 or more 
           times (matching the least amount 
           possible)) 
-------------------------------------------------------------------------------- 
     [a-z]     any character of: 'a' to 'z' 
-------------------------------------------------------------------------------- 
    ){6}      end of grouping 
-------------------------------------------------------------------------------- 
)      end of look-ahead 
-------------------------------------------------------------------------------- 
    .{8}      any character except \n (8 times) 
-------------------------------------------------------------------------------- 
    $      before an optional \n, and the end of the 
          string 
+0

非常好格式化的答案。我的正則表達式不是很強,所以我希望有人可以製作一個,只是爲了好奇。我試過了你的現場演示,但它似乎失敗了,你沒有連續6個小寫字符:'1as1#ddfg @'。 – Mrchief

+1

哇這個答案! @Mrchief你的例子會失敗,因爲它已經超過8個字符,也打破了規則1和2? – iCodeLikeImDrunk

+2

@ yaojiang:是的......出於某種原因,我在6個低級字符部分掛了電話,而忽略了其他條件,當我添加該評論時。我的錯! – Mrchief

3

我錯過了什麼?

的原因您的測試「2 @ 2qwert」和「2 @@ QWERT」被錯誤地符合正則表達式是因爲沒有了什麼東西,需要至少6個小寫字母。基於對這個問題的其他答案和評論,我會說用(?=(.*?[a-z]){6})替換你的(?=.*[a-z])子句。

可以做出一些小的改進:

  • 可以刪除冗餘(?=.*[^a-z])條款,因爲這一切的意思是,該字符串應該至少包含1個非字母,這已經由成立數字和特殊字符要求。
  • 用\ d替換[0-9]。
  • 在匹配字符匹配(。*)前的三個匹配通配符的地方,如果這些引擎非貪婪,RegExp引擎的速度會稍微快一點,這樣在搜索字符串時可以減少回溯一場比賽。這是通過放置一個?之後 * (。*?)。

把這個一起根據您的正則表達式:

/^(?=.*?\d)(?=(.*?[a-z]){6})(?=.*?[@#$*])\S{8,}$/ 

這成功匹配你的第一個4串,但不是最後2

(我原來的響應下面是如果你想有一個可讀的驗證功能。)

function validate(str) 
{ 
    // test for digit 
    if(!/\d/.test(str)) return false; 
    // test for special character 
    if(!/[@#$*]/.test(str)) return false; 
    // test for 6 lowercase letters 
    var letters = str.match(/[a-z]/g); 
    return letters != null && letters.length == 6; 
} 

var tests = [ '[email protected]', '#1asddfg', 'qwe*yt2u', '#qw2wqia', '[email protected]', '[email protected]@qwert' ]; 
for(var i=0 ; i<tests.length ; ++i) 
    document.writeln(tests[i] + ": " + validate(tests[i]) + "<br/>\n"); 
3

由於不滿足條件#3,所以您的破案應該中斷。話雖如此,我認爲它可能是更容易使用JavaScript和正則表達式的組合:

function isValid(input) { 
    return (input && input.length === 8)    /* make sure its 8 characters */ 
     && /[0-9]/.test(input)     /* make sure it contains at least one digit */ 
     && /[@#$*]/.test(input)     /* make sure it contains at least one special character */ 
     && /([^a-z]*[a-z]){6}.*/.test(input);  /* make sure it contains at least 6 lower case chars */ 
} 

console.log(isValid('[email protected]')); // true 
console.log(isValid('#1asddfg')); // true 
console.log(isValid('qwe*yt2u')); // true 
console.log(isValid('#qw2wqia')); // true 
console.log(isValid('[email protected]')); // false 
console.log(isValid('[email protected]@qwert')); // false 
console.log(isValid('[email protected]')); // now true as it satisfies #3 

編輯:更新的基礎上,從@Sniffer投入爲6個字符最小的檢查(這是有趣的學習新的東西,見註釋)

+0

+1尼斯正則表達式/([^a-z]?[a-z]){6}.*/來測試6個不連續的字母。我喜歡你的解決方案比我的更好。 – Matt

+0

@Matt我不認爲'/([^ az]?[az]){6}。* /'有效,嘗試'af34ddfg'它不會匹配 –

+0

@Sniffer你說得對,應該是/ ([^ AZ] * [AZ]){6} * /。 – Matt

2

好吧,我想出了一個正則表達式,可能會做你想要什麼,但你可能不喜歡它的外觀,但原則背後卻是簡單的:

^(?=^.{8}$)(?=\D*[0-9])(?=[^@#$*]*[@#$*])(?=([^a-z]*[a-z]){6})\S{8}$ 

這個表達式第一品牌肯定只有8個字符(?=^.{8}$)

現在表達式檢查是否不存在單個數字(?=\D*[0-9]),那麼它確保有一個特殊符號(?=[^@#$*]*[@#$*])

現在表達式保證有6個小寫字符(?=([^a-z]*[a-z]){6})

所以我們保證有一個數字,一個特殊符號和6個小寫字符,總和是8個字符,所以字符串應該是有效的。

這當然不是最好的方法,因爲您應該將此操作分成多個步驟,但我想嘗試使用單個表達式來實現它,如果您發現任何問題,請讓我知道。

2

此正則表達式確實你需要:

^(?=\D*\d\D*$)(?=[^@#$*]*[@#$*][^@#$*]*$)[@#$*\da-z]{8}$ 

它採用2查找aheads(固定到開始)斷言正好是1位數字和1個特殊字符,還有一個SIM卡所有有效字符的8位字符類別(所有字符都是8位),所以其餘字符必須小寫(不需要精確計數6)。

查看你的測試用例在rubular上的live demo

+0

另一個有趣的解決方案!然而它在這個失敗:'asd1234ghy @' – Mrchief

+0

@Mrchief失敗? 'asd1234ghy @'不應該匹配:問題說*只有一個數字*和*必須有8個字符* - 這個例子因爲這兩個原因而失敗。我已將您的示例添加到此[現場演示](http://rubular.com/r/14scpEiKOB)。讓我知道你的意思。 – Bohemian

+0

你說得對。我只專注於6個低音部分。 – Mrchief