數字(Number)
除正常的數字(digit)之外,還有可能包括正、負號,科學計數法,小數位,甚至用逗號分隔千分位。
邏輯規則:
- 起始位後一定是+/-號,也可以沒有 ^[+-]?
- 至少有一位以上的數字 d+
- 可能會跟著千分位分隔的逗號,暫時不考慮是否一定是3位分隔,規則可以出現一次或多次 (,d+)*
- 如果是小數那麼一定是小數點後帶有至少一位以上的數字,規則僅能出現一次 (.d+)
- 如果是科學計數法,則前面一定是小數,後面跟有e和次冪,規則僅能出現一次 (.d+(ed+))
- 任何數字的結尾必須是數字
滿足上述條件檢驗數字的正規表示式為:^[+-]?d+(,d+)*(.d+(ed+)?)?$
符合該條件的example包括:
- 3 (整數)
- 3.14 (小數)
- +3.14 (帶有+標識數字)
- -2.5 (帶有-標識數字)
- 128,234 (會計計數法)
- 1.9e10 (科學計數法)
且過濾掉小數點重複出現多次,科學技術法不合規或重複出現多次,非數字如720p的字串
此處尤其要注意科學的條件,前面必須是合法小數後面是e和次冪,注意次冪必須有。
電話號碼(Phone Numbers)
美國的電話號碼規則:總計10位數字,但有可能帶有國家號碼1。可以接受的輸入格式包括:
- xxx-xxx-xxxx
- xxx xxx xxxx
- (xxx)xxx-xxxx
- xxxxxxxxxx
- 1 上述格式組合
- +1 上述格式組合
滿足上述條件檢驗美國電話的正規表示式為:^(+?1[s-])?(?d{3})?[s-]?d{3}[s-]?d{4}$
進一步可以將國家號的驗證修改為(+?d+[s-])?,這樣就可以支援諸如+86, 86 , 86-這樣的格式了。
中國的手機規則:總計11位數字,一般情況下不加上任何特殊符號的分隔。如果僅考慮以下4種格式:
- xxxxxxxxxxx
- +86-xxxxxxxxxxx
- +86 xxxxxxxxxxx
- +86xxxxxxxxxxx
滿足上述條件檢驗中國手機號碼的正規表示式為:^(+86[s-]?)?d{11}$
郵件(Email)
由於工作需要,更詳細的查閱了RFC對於郵件地址的標準要求。Google了很久居然始終沒有找到一份靠譜的中文翻譯。在此共享給大家,希望大家不用再去痛苦的翻那RFC晦澀的文件。
根據RFC 3696的規定,郵件地址(Email Address)被@符號分割為以下兩個組成部分:local name和domain name.
Local Name
- 長度不超過64個字元
- 可以由除@、反斜槓()、雙引號(“”)、逗號和方括號([ ])之外,任何ASCII Graphic字元組成。
- 可以使用句號(.),但是不能出現在首尾的位置
- 對於一些特殊情況,如老舊的系統、特殊目的的伺服器,可以使用全部ASCII字元(包括控制字元在內),但是必須使用反斜槓轉義單個字元,或者使用雙引號轉義整個字串。
Domain Name
- 長度不超過255個字元
- 只可以使用字母、數字和短橫線(-)
- 可以使用短橫線(-),但是不能出現在首尾的位置
- 其餘的要求包括頂級域名的白名單,每一級域名不可以超過64個字元、不可全部由數字組成等等
對於日常使用中,忽略Local Name第4點的要求1和Domain Name對域名合法性的過濾,可以使用如下正規表示式檢驗Email的合法性:
^[A-Za-z0-9!#$%&`+/=?^_`{|}~-]+(.[A-Za-z0-9!#$%&`+/=?^_`{|}~-]+)*@([A-Za-z0-9]+(?:-[A-Za-z0-9]+)?.)+[A-Za-z0-9]+(-[A-Za-z0-9]+)?$
如果使用Javascript的話,可以通過split函式,進一步檢驗每一部分的長度。
isemail: function(string){
if(typeof string === "string"){
var regex = /^[A-Za-z0-9!#$%&`*+/=?^_`{|}~-]+(?:.[A-Za-z0-9!#$%&`*+/=?^_`{|}~-]+)*@([A-Za-z0-9]+(?:-[A-Za-z0-9]+)?.)+[A-Za-z0-9]+(?:-[A-Za-z0-9]+)?$/;
var temp = string.split("@");
return regex.test(string) && temp[0].length <= 64 && temp[1].length <= 255;
}
else{
return false;
}
}
郵件的格式較為複雜,雖然實際上允許多級域名,只要長度保證在255個字元以內即可。不過更加常見的情況是,考慮@前面使用字元和.的情況,以及@後面可能會有二級域名的情況。如果不要求嚴格性而只是起到對於使用者的提示作用的話,滿足上述條件檢驗郵件的正規表示式為:^[w.]+(+[w.]+)?@w+(.w+){1,2}$
如果可能的話,理解了原理之後,還是更加推薦使用成熟的庫自帶的email檢驗函式,畢竟重複造輪子不是一件非常有效率的事情。
密碼(Password)
不同強度的密碼,
要求至少包含數字或字母:[da-zA-Z]d+[a-zA-Z]+[da-zA-Z]
必須數字、字母和特殊字元3種混排的:
(d+[a-zA-Z]+[-=\[];`,./~!@#$%^&*()_+|{}:"<>?]+) #數字開頭
=[];`,./~!@#$%^&()_+|{}:”<>?]+[a-zA-Z]+) #數字開頭
|(d+[-
|([a-zA-Z]+d+[-=\[];`,./~!@#$%^&*()_+|{}:"<>?]+) #字母開頭
=[];`,./~!@#$%^&()+|{}:”<>?]+d+) #字母開頭
|([a-zA-Z]+[-
|([-=\[];`,./~!@#$%^&*()_+|{}:"<>?]+d+[a-zA-Z]+) #特殊字元開頭
=[];`,./~!@#$%^&*()+|{}:”<>?]+[a-zA-Z]+d+) #特殊字元開頭
|([-
IP地址
IP地址是由4個使用句號(.)分割的數字序列組成,每段的數值取值在0-255之間。
由於數字會被當成字元看待,而沒有大小關係,使用正規表示式檢驗數字範圍是一件非常麻煩的事情。
檢驗IP地址的正規表示式如下:
(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9]).{3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])
使用Javascript,稍微優雅一點的表達方式
ip: function(string){
var octet = `(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])`;
var ip = `(?:` + octet + `\.){3}` + octet;
var ipRE = new RegExp( `^` + ip + `$` );
return ipRE.test(string);
}
HTML
HTML更為推薦使用其他的方式而非正規表示式進行過濾。
獲取Tag:<(w+)
獲取Tag內容:>([ws])<
獲取Attribute的值:=`([w://.])
更新記錄
2014年9月5日修改
原本的正規表示式中沒有考慮到yeelan0319@sf.com.32y8498這樣的內容也會被判定為true。還是對於正規表示式並非“全部字串匹配”,而是隻要出現“符合正規表示式規定的內容即可”的理解不夠透徹。說來說去最後好像還是推薦使用已經成熟的庫比較好,畢竟重複造輪子是一件太過於低效率的事情
2015年3月4日修改
根據RFC規定,更新了符合RFC詳細要求的email的正規表示式。
新增了IP地址的檢驗正則
-
雖然此處沒有考慮Local Name的第4點要求,但是RFC中其實規定,瀏覽器(Client Side)端檢驗不應該拒絕該格式的輸入,而應該交由郵件伺服器實際在執行過程中判斷其合法性,因為這樣的格式其實是完全合法的。此處其實是我偷懶了。 ↩