javascript - 尝试在用户键入时使用 javascript 正则表达式验证日期条目

标签 javascript jquery regex validation date

我正在尝试使用一些日期验证来更新较旧的应用程序,当用户在文本字段中键入它时。

我这里有一个简单的演示 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/

相关文章:

javascript - 如何在 laravel 中应用客户端密码加密

javascript - Canvas 图像到 Blob ,改变图像大小

jquery - 让 jquery 只运行一次

javascript - jQuery 对 javascript 类方法的 AJAX 调用

ruby-on-rails - 带有 ruby​​ on rails 形式的正则表达式模式

php - 正则表达式限制与之前匹配的字符串的匹配

javascript - 垂直对齐绝对定位的div

javascript - 全日历。从外部列表中删除拖动的事件

javascript - 单击jquery隐藏div

regex - 使用 NSRegularExpression 匹配的奇怪字符串范围行为