我正在尝试使用一些日期验证来更新较旧的应用程序,当用户在文本字段中键入它时。
我这里有一个简单的演示 http://jsfiddle.net/7d82j0ky/2/如果您输入以下日期:
- 1972 年 5 月 24 日(有效)
- 05/24/2020(在这种情况下年份无效,当前年份是我们达到最大值的年份)
- 05/32/1972(本例中的日期无效)
正则表达式有效,但在您输入 MM/DD/YYYY 的完整日期格式之前它是无效的。如果您打开浏览器控制台,您会看到它在您键入时控制台输出消息。
我希望在用户键入时进行验证,因此每个字符如果存在无效字符,我想阻止该无效字符的默认行为,因此永远不会添加它,所以:
- 05/24 就可以了
- 05/32 不行,这两个不应该通过阻止该键事件的默认行为出现在 UI 中,因此您在键入时只会在文本字段中看到“05/3”
- 0a 不行,就像上面的“a”应该被阻止,这样您在键入时只会在文本字段中看到“0”。
在您输入时匹配正则表达式的最佳方式是什么?
我这里有一些日期正则表达式的测试用例 https://regex101.com/r/M8habw/1/根据我们在应用程序中关心的日期,它们似乎都运行良好。我不是很擅长正则表达式,但这并不难。
这是满足在此处发布的 jsfiddle 代码:
<input class="input" type="text" maxlength="10" placeholder="MM/DD/YYYY"/>
$('.input').on('input', function(e) {
var regex = /^(0[1-9]|1[0-2])\/(0[1-9]|1\d|2\d|3[01])\/((19[2-9]\d{1})|20[0|1]\d{1})$/g;
if (!this.value.match(regex)) {
console.log('nope');
e.preventDefault();
} else {
console.log('yep');
}
});
最佳答案
您不能仅使用正则表达式来验证日期。或者至少不是一个合理的。如果它考虑到闰年等,那就太先进了。
不过您可以使用更多的 javascript 来做到这一点。在您的 oninput 函数中,您可以去除非数字字符,使用您的数字串(确保它是正确的日期)并且仅将其他字符(“格式化字符”)添加回它们应该在之后的位置。
如果你有一个格式为 MMDDYYYY
的部分日期(但可能只填写了一些字符)并且你想确保这不会产生无效日期,你可以使用类似下面。
一个技巧是在 Javascript 中创建无效日期并不总是会产生无效结果,它只会溢出,因此 2019-01-32
将为您提供 2019-02-01 的日期
。虽然在某些情况下有用,但当我们试图检测无效日期时,这对我们来说很烦人。但是我们可以确保表示生成日期的字符串与我们提供的相同。如果不同,我们就处于“溢出”的情况。
function hasErrors(val) {
let month = val.slice(0, 2);
let day = val.slice(2, 4);
let year = val.slice(4);
// The string is fully empty - not an invalid input
if (!month.length) {
return false;
}
// Only one of the months digits is filled out. Assume the rest will be filled out by the smallest possible valid value
// (optimistic heuristic)
if (month.length === 1) {
month += month === '0' ? '1' : '0';
}
// Invalid month
if (+month > 12 || +month <= 0) {
return true;
}
// Month valid but day not filled - ok
if (!day.length) {
return false;
}
// Only part of the day filled, same as above with the month
if (day.length === 1) {
day += day === '0' ? '1' : '0';
}
// Days always invalid
if (+day > 31 || +day <= 0) {
return true;
}
// If the year is not fully filled out, use any year with a 29 Feb
if (year.length < 4) {
year = '1972';
}
// Make sure the date is valid (e.g. no 31st of April)
let sourceStr = [year, month, day].join('-');
let date = new Date(sourceStr);
if (!+date || date.toISOString().slice(0, 10) !== sourceStr) {
return true;
}
// No error was detected
return false;
}
这是一个 example fiddle .
正如其他人所提到的,从用户体验的 Angular 来看,阻止用户输入是一个非常糟糕的主意。这会使事情变得困惑,尤其是在尝试编辑字符串的中间而不是结尾时。更好的解决方案是仅通过样式指示错误。这是一个 example fiddle不阻止用户输入(只是更改了第 76 行附近的部分)。
关于javascript - 尝试在用户键入时使用 javascript 正则表达式验证日期条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56637586/