2016-11-30 21 views
2

我想使用正則表達式和POSIX字符類在R中驗證密碼。我知道大量的正則表達式,但不知道POSIX塊。在查詢正則表達式問題時,我查了一下SO資源,還有半打SO問題和答案,如thisthat。密碼的規則是:使用正則表達式和POSIX字符類驗證R中的密碼

  • 一個大寫字母
  • 一個小寫字母
  • 一個或多個特殊字符(ASCII標點符號)
  • 8和32之間的字符
  • ASCII可見和空格字符只有

我已經嘗試了一些代碼變體,如被註釋掉的代碼所示。我開始在較低的層次上構建正則表達式,然後按照正則表達式來處理,這些正則表達式應該包含所有需求。

ValidatePassword <- function(stringChar) { 
    # validPW <- "([[:lower:]]+[[:upper:]]+){8,32}" 
    # validPW <- "[[:lower:]]+[[:upper:]]+" 
    # validPW <- "^(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]])[[:print:]]{8,32}$" 
    # validPW <- "^(?:[[:lower:]])(?:[[:upper:]])(?:[[:punct:]])[[:print:]]{8,32}$" 
    # validPW <- "^(?:.*[[:lower:]])(?:.*[[:upper:]])(?:.*[[:punct:]])[[:print:]]{8,32}$" 
    # validPW <- "^([[:lower:]]+|[[:upper:]]+|[[:punct:]]+)[[:print:]]{8,32}$" 
    # validPW <- "^(?=.*[a-z])(?=.*[A-Z])(?=.*[[:punct:]])[[:print:]]{8,32}$" 
    # validPW <- "^([[:lower:][:upper:][:punct:]])[[:print:]]{8,32}" 
     validPW <- "^([[:lower:]]+|[[:upper:]]+|[[:punct:]]+)[[:print:]]{8,32}$" 
     return(length(grep(validPW, stringChar, value = TRUE))) 
    } 
    ifelse(ValidatePassword("#Password"), "valid", "not valid") # valid 
    ifelse(ValidatePassword("_PASSWORD"), "valid", "not valid") # not valid 
    ifelse(ValidatePassword("Password"), "valid", "not valid") # not valid 
    ifelse(ValidatePassword("password"), "valid", "not valid") # not valid 
    ifelse(ValidatePassword("passwor"), "valid", "not valid") # not valid 
    ifelse(ValidatePassword("pAsswords"), "valid", "not valid") # not valid 
    ifelse(ValidatePassword("Pa&sword"), "valid", "not valid") # valid 
    ifelse(ValidatePassword("Pa&s word"), "valid", "not valid") # valid 

我意識到即使結果顯示「有效」,代碼也不能正常工作。有人可以提供幫助嗎? ty

回答

1

你可以使用下面的正則表達式驗證:

is.validpw <- function(x) { 
    grepl('(?x)     # free-spacing mode 
     ^     # assert position = beginning of string 
      (?=.*[[:upper:]]) # match one uppercase letter 
      (?=.*[[:lower:]]) # match one lowercase letter 
      (?=.*[[:punct:]]) # match one special character 
      [ -~]{8,32}  # match printable ascii characters 
      $     # assert position = end of string', x, perl = TRUE) 
} 

is.validpw(c('#Password', '_PASSWORD', 'Password', 'password', 
      'passwor', 'pAsswords', 'Pa&sword', 'Pa&s word')) 

## [1] TRUE FALSE FALSE FALSE FALSE FALSE TRUE TRUE 
+0

這個答案通過了長度測試,再加上幾個測試,我還沒有見過「free-spacing mode」,你可以稍微解釋一下,或者指給我解釋一下嗎?另外,(?x)是做什麼的? –

+1

free-spacing模式允許在正則表達式中使用空格你可以在整個過程中進行評論,解釋每個部分。'(?x)'是允許這種模式的內聯修飾符。 – hwnd

+0

我很好奇並將'[ - 〜]'重新編碼爲'[[:print:]]',最後破壞代碼,允許無效的密碼「pass word」潛入。 –

1

我傾向於比l33t正則表達式更喜歡可讀的邏輯,所以其他人類(或者未來的自己)可以理解發生了什麼。

is_valid_password <- function(x) { 
    grepl('((?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{8,32})', x, perl=TRUE) & 
    grepl("[[:print:][:space:]]", x) 
} 

pwds <- c("#Password", "_PASSWORD", "Password", "password", "passwor", "pAsswords", "Pa&sword", "Pa&s word") 

is_valid_password(pwds) 
## [1] TRUE FALSE FALSE FALSE FALSE FALSE TRUE TRUE 
+0

我不相信這是通過最大長度測試條件。我在pwds變量中添加了「123456789O12345678(o1234567890123」),並且該函數返回TRUE。我仍然在看它是否可以計算出來。 –