我希望使用此RegEx为特定日期格式(与Date.parse-NaN不兼容)进行简单的捕获和测试程序:
/(\d{1,2})\/(\d{1,2})\/(\d{2,4})/ //day/month/year
它适用于rubular测试仪,但在chrome中使用它会产生奇怪的结果:
dateRegex.test("19111/7/1992")
> true
"19111/7/1992".match(dateRegex) //Wrong on purpose
> ["11/7/1992", "11", "7", "1992"] //Why is it matching 11?
我需要注意哪些特定于JavaScript RegEx?
答案 0 :(得分:1)
尝试使用
^(\d{1,2})\/(\d{1,2})\/(\d{2,4})$
^
在字符串的开头断言位置,$
在字符串的结尾处(或在字符串末尾的换行符之前,如果有的话)断言位置。
答案 1 :(得分:1)
首先,这不是处理日期的正确方法。它可以将99/99/9999
解析为日期。我想你知道这件事。
现在回答你的问题,为什么它解析了11/7/1992
?因为你没有提供任何边界,它匹配字符串的一部分。你可以用几种方式做到这一点。
这会强制整个字符串从结尾开始匹配锚点(^
$
)。
/^(\d{1,2})\/(\d{1,2})\/(\d{2,4})$/
使用\b
来区分数字。这将帮助您从任何字符串的中间进行解析。
/\b(\d{1,2})\/(\d{1,2})\/(\d{2,4})\b/
答案 2 :(得分:1)
其他答案应该很好地解释实际的匹配程序。
要进一步验证日期,您可以执行以下操作:
function valiDate(d) {
var v, m = d.match(/^(\d{1,2})\/(\d{1,2})\/(\d{1,4})$/);
if (!m)
return false;
v = new Date(m[3], m[2] - 1, m[1]);
return m[1] == v.getDate() &&
m[2] == v.getMonth() + 1 &&
m[3] == v.getFullYear()
;
}
或者可能更快:
function valiDate(d) {
function leap(y) {
return !((y%4)||(!(y%100) && (y%400)));
}
var m = d.match(/^(\d{1,2})\/(\d{1,2})\/(\d{1,4})$/);
// Not match || date or month below 1, or month above 12
if (!m || m[1] < 1 || m[2] < 1 || m[2] > 12) {
return false;
// Jan,Mar,May,Jul,Aug,Oct,Dec
} else if ([2,4,6,9,11].indexOf(+m[2]) < 0) {
return m[1] < 32;
// Feb
} else if (m[2] === '2') {
return m[1] < 29 ? true :
m[1] < 30 && leap(+m[3]);
// Apr,Jun,Sep,Nov
} else {
return m[1] < 31;
}
}
答案 3 :(得分:0)
你的正则表达式表现正常。特别是以下是:
19111/7/1992
^
matching starts at this point, everything before that is ignored
你需要的是指定你的正则表达式应该从字符串的开头开始,并在字符串的结尾处结束:
/^(\d{1,2})\/(\d{1,2})\/(\d{2,4})$/
...请注意^
和$
,这些会导致开头或结尾处的任何额外字符无法使用正则表达式。