You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何结合正则表达式实现jQuery-Mask-Plugin日期输入验证?

解决jQuery-Mask-Plugin的有效日期掩码问题

我懂你遇到的痛点——基础的00-00-0000掩码只能保证格式,没法阻止用户输入99-99-9999这种完全无效的日期。你之前尝试用自定义翻译规则的思路是对的,但问题出在插件的translation规则是针对单个字符占位符的,不能直接把整个日/月的正则组塞进去。下面给你两种解决方案,从基础到进阶:

基础版:匹配你的正则规则

先实现你提供的正则/(0[1-9]|[12]\d|3[01])-(0[1-9]|1[0-2])-([12]\d{3})/的限制,确保日在01-31、月在01-12、年在1000-2999范围内:

<input id="mydateinput" name="mydateinput" type="text"/>
$('#mydateinput').mask('00-00-0000', {
  translation: {
    // 定义通用数字占位符
    '0': {
      pattern: /[0-9]/,
      optional: false
    }
  },
  // 关键:用onKeyPress实时验证完整输入
  onKeyPress: function(val, e, field, options) {
    // 当输入满10位(完整日期格式)时触发验证
    if (val.length === 10) {
      var validDateRegex = /(0[1-9]|[12]\d|3[01])-(0[1-9]|1[0-2])-([12]\d{3})/;
      if (validDateRegex.test(val)) {
        field.removeClass('invalid-date');
      } else {
        field.addClass('invalid-date');
        // 可选:添加提示,比如弹窗或输入框提示
        // alert('请输入有效的dd-mm-yyyy格式日期');
      }
    } else {
      // 未输入完整时移除错误样式
      field.removeClass('invalid-date');
    }
  },
  // 可选:输入完成后再次验证兜底
  onComplete: function(val) {
    var validDateRegex = /(0[1-9]|[12]\d|3[01])-(0[1-9]|1[0-2])-([12]\d{3})/;
    if (!validDateRegex.test(val)) {
      $('#mydateinput').addClass('invalid-date');
    }
  }
});

进阶版:精准限制日期(考虑月份天数+闰年)

上面的基础版还允许输入31-04-2024(四月没有31天)或29-02-2023(2023不是闰年)这类日期。我们可以通过自定义每个字符的匹配规则,结合已输入的月份/年份来动态限制日期:

$('#mydateinput').mask('DD-MM-YYYY', {
  translation: {
    'D': {
      pattern: /[0-3]/,
      fallback: '0'
    },
    'd': {
      pattern: function(val, opts, field) {
        var fullInput = field.val();
        var dayFirstDigit = fullInput.charAt(0);
        var month = fullInput.substring(3,5);
        
        // 处理3开头的日期:只有非小月(4/6/9/11)才能有31号
        if (dayFirstDigit === '3') {
          const shortMonths = ['04','06','09','11'];
          return shortMonths.includes(month) ? /[0]/ : /[01]/;
        }
        // 处理0开头的日期:只能是1-9
        else if (dayFirstDigit === '0') {
          return /[1-9]/;
        }
        // 处理1/2开头的日期:二月特殊处理
        else {
          if (month === '02') {
            var year = fullInput.substring(6,10);
            // 判断闰年规则:能被4整除但不能被100整除,或能被400整除
            const isLeapYear = (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
            // 非闰年二月最多28号,闰年最多29号
            return dayFirstDigit === '2' ? (isLeapYear ? /[0-9]/ : /[0-8]/) : /[0-9]/;
          }
          return /[0-9]/;
        }
      }
    },
    'M': {
      pattern: /[01]/,
      fallback: '0'
    },
    'm': {
      pattern: function(val, opts, field) {
        var monthFirstDigit = field.val().charAt(3);
        // 1开头的月份只能是10/11/12
        return monthFirstDigit === '1' ? /[0-2]/ : /[1-9]/;
      }
    },
    'Y': {
      pattern: /[12]/,
      fallback: '2'
    },
    'y': {
      pattern: /[0-9]/,
      fallback: '0'
    }
  },
  // 依然保留完整输入后的正则验证作为兜底
  onComplete: function(val) {
    var validDateRegex = /(0[1-9]|[12]\d|3[01])-(0[1-9]|1[0-2])-([12]\d{3})/;
    if (!validDateRegex.test(val)) {
      $('#mydateinput').addClass('invalid-date');
    }
  }
});

为什么你之前的写法无效?

你之前尝试用ZX和YK作为占位符,直接把整个日/月的正则塞进去,但jQuery-Mask-Plugin的translation规则是每个占位符对应单个字符的匹配规则,插件无法识别多字符的占位符正则,所以这种写法不会生效。必须把每个字符位置单独配置规则,或者结合事件回调做整体验证。

内容的提问来源于stack exchange,提问作者Henrique C.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:46:53