2011-04-10 74 views
2

我想了解什麼不對的正則表達式:正則表達式來驗證用戶名

'/^[a-z0-9-_\.]*[a-z0-9]+[a-z0-9-_\.]*{4,20}$/i'

我試圖做的是驗證用戶名。允許的字符是字母數字,短劃線,下劃線和點。我想實現的限制是至少有一個字母數字字符,這樣用戶就不會被允許有這樣一個綽號:_-_.

我現在使用的功能是:

function validate($pattern, $string){ 
    return (bool) preg_match($pattern, $string); 
} 

謝謝。

編輯

正如@mario說,是的,T這裏是*{4,20}問題。 我試過現在要做的是增加()但這不是工作作爲例外:

'/^([a-z0-9-_\.]*[a-z0-9]+[a-z0-9-_\.]*){4,20}$/i'

現在「AA - AA」相匹配,但它不匹配「aa--家庭」和'--aa'。 還有其他建議嗎?

編輯

也許有人想否認沒有好看的用戶名,如 「_ .. -a」。 此正則表達式將拒絕有連續的非字母數字字符:

/^(?=.{4,20}$)[a-z0-9]{0,1}([a-z0-9._-][a-z0-9]+)*[a-z0-9.-_]{0,1}$/i

在這種情況下_-this-is-me-_將不匹配,但_this-is-me_將匹配。

有一個愉快的一天,並感謝所有:)

+0

你嘗試的東西,如http://regexpal.com調試? – 2011-04-10 01:58:58

+0

感謝您的建議。我會試一試 – s3v3n 2011-04-10 01:59:43

+2

有些人可能會認爲它是一個cop-out,但對於這樣的事情(這很容易表達沒有正則表達式),我個人更喜歡保持從正則表達式清醒。爲什麼不循環遍歷字符,檢查它們是否都是有效字符,並且至少有一個是字母數字? – 2011-04-10 02:03:38

回答

6

不要試圖把它塞進一個正則表達式。讓你的生活更簡單,使用兩個步驟的方法:

return (bool) 
preg_match('/^[a-z0-9_.-]{4,20}$/', $s) && preg_match('/\w/', $s); 

這個錯誤在你的正則表達式可能是的*{n,m}相混淆。你可以只有一個量詞,而不是*{4,20}


非常好,這裏是麻煩的解決方案,以你想要的東西:

preg_match('/^(?=.{4})(?!.{21})[\w.-]*[a-z][\w-.]*$/i', $s) 

斷言斷言長度,而第二部分可確保至少有一個字母是存在的。

+0

請參閱我對Johnsyweb的回答的評論,以瞭解爲什麼我不能(也不想)將它分成兩個檢查。是的,現在我清楚地看到問題是*和{4,20}的混合。請參閱編輯。 – s3v3n 2011-04-10 02:22:18

+0

@ s3v3n:這是對我在答案中提出的觀點的一個很好的證明 - 兩個正則表達式清晰易懂。 @mario沒有利用機會根據哪個檢查失敗向用戶提供量身定製的反饋,但是您可以! – Johnsyweb 2011-04-10 02:23:19

+1

@ s3v3n:查看複雜解決方法的更新。我仍然會說這不是你應該做的。 – mario 2011-04-10 02:32:44

1

它可能只是如果微調的問題,你可以嘗試這樣的事:

if (preg_match('/^[a-zA-Z0-9]+[_.-]{0,1}[a-zA-Z0-9]+$/m', $subject)) { 
    # Successful match 
} else { 
    # Match attempt failed 
} 

匹配:

  • A_B < - 你可能不想要這個。
  • ysername
  • 用戶名
  • 1254_2367
  • fg3123as

不匹配:

  • l__asfg
  • AHA_ar3f!
  • sAD_ASF _# 「#T_
  • 」#%「 &#」 E
  • __-。ASD
  • 用戶名
  • 1_ _ _

不匹配,你可能想成爲比賽:

  • 1_5_2
  • this_is_my_name
+0

其實我是說它應該從字符串的開頭匹配。將^放在方括號內會產生否定的效果。 – s3v3n 2011-04-10 02:02:11

+0

另外,正如我所說,我試圖匹配不僅字母數字,而且還有一些字符。問題是否認至少缺少一個字母數字字符。 – s3v3n 2011-04-10 02:05:11

+0

是啊我的壞我注意到我不清楚我的答案,並編輯它。 – FRoZeN 2011-04-10 02:20:26

2

試試這個一個inst EAD:

'/[a-z0-9-_\.]*[a-z0-9]{1,20}[a-z0-9-_\.]*$/i' 
+0

我說不要開始一個字母或數字,你的正則表達式究竟是什麼,但至少包含一個字母或數字,這就是爲什麼我把[a-z0-9] +放在midle中。 – s3v3n 2011-04-10 02:06:51

+0

啊現在我得到你的問題。請參閱編輯 – worenga 2011-04-10 02:12:09

+0

是的,這可以解決問題,唯一剩下的問題就是檢查用戶名的長度。 – s3v3n 2011-04-10 02:16:27

0

試試這個:

^[a-zA-Z][-\w.]{0,22}([a-zA-Z\d]|(?<![-.])_)$ 

從相關的問題:Create one RegEx to validate a username

+0

作爲第一步,它檢查用戶名是否以一個字母開頭,這不正是我想要做的。 – s3v3n 2011-04-10 02:07:49

1

很明顯,我認爲你應該分成兩個檢查此!

首先檢查他們是否使用了所有有效的字符。如果他們不是,那麼你可以告訴他們他們正在使用無效字符。

然後檢查它們是否至少有一個字母數字字符。如果他們不是,那麼你可以告訴他們他們必須。

這裏有兩個明顯的優點:向用戶提供更有意義的反饋和更清晰的代碼來讀取和維護。

+0

這會增加複雜性。是的,這不是世界末日,但這並不是一個複雜的正則表達式來分裂它。正如我之前所說的,我有一個包含模式的類Validator,我真的不想讓事情複雜化並在那裏實現兩步驗證。 – s3v3n 2011-04-10 02:13:08

+1

@ s3v3n:我非常不同意。這將*刪除*複雜性。事實證明,你已經在這裏複雜了事實,即你的正則表達式不能達到你想要的目標,而且你「正試圖理解錯誤」。 – Johnsyweb 2011-04-10 02:18:28

+1

我同意Johnsyweb。如果你想驗證下一個文件輸入怎麼辦?它很難找到上傳錯誤的正則表達式,0字節的文件等。 你在自己的體系結構中限制太多。它現在可能有效,但如果你想要更深入一些呢? – worenga 2011-04-10 02:42:38

1

下面是一個簡單的單正則表達式溶液(詳細):

$re = '/ # Match password having at least one alphanum. 
    ^     # Anchor to start of string. 
    (?=.*?[A-Za-z0-9]) # At least one alphanum. 
    [\w\-.]{4,20}  # Match from 4 to 20 valid chars. 
    \z     # Anchor to end of string. 
    /x'; 

在動作(短形式):

function validate($string){ 
    $re = '/^(?=.*?[A-Za-z0-9])[\w\-.]{4,20}\z/'; 
    return (bool) preg_match($re, $string); 
} 
0
^[A-Za-z][A-Za-z0-9]*(?=.{3,31}$)[a-z0-9]{0,1}([a-z0-9._-][a-z0-9]+)*[a-z0-9.-_]{0,1}$ 

這將驗證用戶名

  1. 開始與阿爾法
  2. 接受下劃線虛線和點
  3. 不允許有空格