如何结合正则表达式实现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.
相关产品推荐
相关产品推荐

