JavaScript分步實現(xiàn)一個出生日期的正則表達(dá)式
簡言
在表單驗證中,經(jīng)常會用正則表達(dá)式做出生日期校驗。本文把出生日期分割成幾個部分,分步地介紹了實現(xiàn)一個出生日期校驗的完整過程。相信您在理解了本篇的內(nèi)容后,對編寫正則表達(dá)式會有更深入的理解和更強(qiáng)的信心。

我們將一個形式如 2018-06-15 的出生日期分割個年份,月份和日期三個組成部分,分別來編寫相應(yīng)的正則。
1 年份正則
首先給出年份正則表達(dá)式的規(guī)則定義:
- 年份由4位數(shù)字組成
- 只接受19,20開頭的年份
根據(jù)以上規(guī)則,很容易寫出年份的正則表達(dá)式:
var pattern = /^(19|20)\d{2}$/;
//輸出 true
console.log(pattern.test("2008"));
其中/ /兩個斜杠及其中間的字符是正則表達(dá)式直接量的定義;^表示匹配字符串的開頭,$表示匹配字符串的結(jié)尾;^(19|20)表示匹配以19或20開頭的字符串,一對小括號作用是將幾項組合為一個單元;而\d{2}表示匹配任意ASCII數(shù)字2次,\d等價于[0-9],而{2}則表示匹配前一項2次。
上述正則表達(dá)式可以匹配1900至2099這些年份,如果想限制年份的范圍,增加規(guī)則如下:
- 年份起始于1920年
- 年份終止于2018年
根據(jù)以上規(guī)則,變更正則表達(dá)式如下:
var pattern = /^(19[2-9]\d{1})|(20((0[0-9])|(1[0-8])))$/;
//輸出 false
console.log(pattern.test("1916"));
//輸出 true
console.log(pattern.test("2008"));
//輸出 false
console.log(pattern.test("2022"));
2 月份正則
首先給出月份正則表達(dá)式的規(guī)則定義:
- 月份可以是1-12
- 月份如果是1-9,則前面可加0
根據(jù)以上規(guī)則,給出如下正則及簡單測試:
var pattern = /^((0?[1-9])|(1[0-2]))$/;
//輸出 false
console.log(pattern.test("19"));
//輸出 true
console.log(pattern.test("02"));
//輸出 true
console.log(pattern.test("2"));
//輸出 true
console.log(pattern.test("11"));
3 日期正則
首先給出日期正則表達(dá)式的規(guī)則定義:
- 日期可以是1-31
- 如果日期是1-9,則前面可加0
根據(jù)以上規(guī)則,給出如下正則及簡單測試:
var pattern = /^((0?[1-9])|([1-2][0-9])|30|31)$/;
//輸出 false
console.log(pattern.test("32"));
//輸出 true
console.log(pattern.test("02"));
//輸出 true
console.log(pattern.test("2"));
4 組合校驗
根據(jù)上述的年份正則,月份正則,日期正則組合形成出生日期的正則表達(dá)式:
var pattern = /^((19[2-9]\d{1})|(20((0[0-9])|(1[0-8]))))\-((0?[1-9])|(1[0-2]))\-((0?[1-9])|([1-2][0-9])|30|31)$/;
//輸出 true
console.log(pattern.test("1923-3-18"));
//輸出 true
console.log(pattern.test("1923-4-31"));
//輸出 true
console.log(pattern.test("1923-2-29"));
//輸出 true
console.log(pattern.test("2016-2-29"));
從以上測試結(jié)果可以看出,上述正則驗證還不完善,主要是2,4,6,9,11月份的天數(shù)問題。
5 完善
根據(jù)第4步的問題,增加限定規(guī)則如下:
- 4,6,9,11月沒有31日
- 2月平年是28天
- 2月閏年是29天
平年閏年判定:
能被4整除的年份是閏年,不能被4整除的年份是平年。但是如果是整百年,就只有能被400整除才是閏年,否則就是平年。
根據(jù)新增規(guī)則及說明,給出下面正則函數(shù)及測試:
var checkBirth = function (val) {
var pattern = /^((?:19[2-9]\d{1})|(?:20(?:(?:0[0-9])|(?:1[0-8]))))\-((?:0?[1-9])|(?:1[0-2]))\-((?:0?[1-9])|(?:[1-2][0-9])|30|31)$/;
var result = val.match(pattern);
if(result != null) {
var iYear = parseInt(result[1]);
var month = result[2];
var date = result[3];
if(/^((0?[469])|11)$/.test(month) && date == '31') {
return false;
} else if(parseInt(month) == 2){
if((iYear % 4 ==0 && iYear % 100 != 0) || (iYear % 400 == 0)) {
if(date == '29') {
return true;
}
}
if(parseInt(date) > 28) {
return false;
}
}
return true;
}
return false;
}
//輸出 true
console.log(checkBirth("1923-3-18"));
//輸出 false 4月份沒有31日
console.log(checkBirth("1923-4-31"));
//輸出 false 平年
console.log(checkBirth("1923-2-29"));
//輸出 true 閏年
console.log(checkBirth("2016-2-29"));
上述正則表達(dá)式中利用了String的match()方法,該方法唯一參數(shù)是一個正則表達(dá)式,返回的是一個由匹配結(jié)果組成的數(shù)組。數(shù)組的第一個元素就是匹配的字符串,余下的元素則是正則表達(dá)式中用圓括號括起來的子表達(dá)式。而(:?...)這種形式多次出現(xiàn),該種方式表示只是把項組合到一個單元,但不記憶與該組相匹配的字符。利用該種方法按照正則匹配的順序分別取出了年月日項,以便后序比較。
根據(jù)上述分析與測試,我們不但實現(xiàn)了年月日的正則的一般判定,還實現(xiàn)了日期范圍及2,4,6,9,11月等特殊月份天數(shù)的處理,測驗結(jié)果達(dá)到了我們設(shè)定的目標(biāo)。
根據(jù)上述講解和分析,我們可以調(diào)整相應(yīng)的限定規(guī)則,使其滿足于特定場景下的項目需要。
延伸
根據(jù) V2EX網(wǎng)友 xiangyuecn 的意見,上述checkBirth的邏輯代碼太多,確實有點 low?,F(xiàn)將上述代碼更新如下:
var checkBirth = function (val) {
var pattern = /^((19[2-9]\d{1})|(20((0[0-9])|(1[0-8]))))\-((0?[1-9])|(1[0-2]))\-((0?[1-9])|([1-2][0-9])|30|31)$/;
if(pattern.test(val)) {
var date = new Date(val);
var month = val.substring(val.indexOf("-")+1,val.lastIndexOf("-"));
return date && (date.getMonth()+1 == parseInt(month));
}
return false;
}
總結(jié)
以上所述是小編給大家介紹的JavaScript分步實現(xiàn)一個出生日期的正則表達(dá)式,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
HTML+CSS+JavaScript實現(xiàn)可拖拽模態(tài)框
這篇文章主要為大家詳細(xì)介紹了HTML+CSS+JavaScript實現(xiàn)可拖拽模態(tài)框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-07-07
Javascript自執(zhí)行匿名函數(shù)(function() { })()的原理淺析
匿名函數(shù)就是沒有函數(shù)名的函數(shù)。這篇文章主要介紹了Javascript自執(zhí)行匿名函數(shù)(function() { })()的原理淺析的相關(guān)資料,需要的朋友可以參考下2016-05-05
JavaScript判斷變量名是否存在數(shù)組中的實例
下面小編就為大家分享一篇JavaScript判斷變量名是否存在數(shù)組中的實例,具有很的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-12-12
詳解如何準(zhǔn)確判斷JavaScript中的數(shù)據(jù)類型
JavaScript中,我們經(jīng)常需要判斷數(shù)據(jù)類型以便于正確地處理數(shù)據(jù),本文將介紹JavaScript中的數(shù)據(jù)類型判斷技術(shù),包括typeof操作符、instanceof操作符、Object.prototype.toString方法以及ES6新增的一些數(shù)據(jù)類型判斷方法,需要的朋友可以參考下2023-08-08
如何消除inline-block屬性帶來的標(biāo)簽間間隙
這篇文章主要介紹了如何消除inline-block屬性帶來的標(biāo)簽間間隙的相關(guān)資料,需要的朋友可以參考下2016-03-03

