JavaScript/AngularJS中信用卡有效期(mm/yy)正则验证问题
信用卡有效期(mm/yy)完整验证方案
你当前的正则已经正确校验了月份范围,但年份部分仅限制为两位数字,导致会匹配到过期或无效的年份(如00、12)。要实现完整的验证,我们需要将格式校验和年份有效性校验结合起来,具体方案如下:
1. 基础格式校验(正则实现)
先保留你原有的月份校验逻辑,确保输入符合mm/yy的格式,月份在01-12之间:
const formatRegex = /^(0[1-9]|1[0-2])\/\d{2}$/;
这一步用来过滤格式错误的输入(比如13/23、05/3这类不符合要求的内容)。
2. 动态年份有效性校验(JavaScript逻辑)
因为年份的有效范围是随时间变化的(比如2023年时,22及以前的年份都已过期),所以我们需要通过当前日期来动态判断:
function isValidExpiryDate(input) { // 第一步:校验格式是否正确 if (!formatRegex.test(input)) { return false; } // 拆分月份和年份并转为数字 const [inputMonth, inputTwoDigitYear] = input.split('/').map(num => parseInt(num, 10)); const now = new Date(); const currentYear = now.getFullYear(); const currentTwoDigitYear = currentYear % 100; const currentMonth = now.getMonth() + 1; // 注意:JS中月份是0-11,所以要+1转为1-12 // 计算输入年份对应的完整年份(默认按20xx处理,符合信用卡年份的常规规则) const inputFullYear = 2000 + inputTwoDigitYear; // 分情况判断有效性: // 情况1:输入年份大于当前两位年份 → 未过期,有效 if (inputTwoDigitYear > currentTwoDigitYear) { return true; } // 情况2:输入年份等于当前两位年份 → 需确保月份不早于当前月份 else if (inputTwoDigitYear === currentTwoDigitYear) { return inputMonth >= currentMonth; } // 情况3:输入年份小于当前两位年份 → 已过期,无效 else { return false; } } // 测试用例 console.log(isValidExpiryDate("11/23")); // 若当前是2023年10月及以前 → true;11月及以后也返回true console.log(isValidExpiryDate("09/23")); // 若当前是2023年10月 → false(已过期) console.log(isValidExpiryDate("05/25")); // true(未来年份) console.log(isValidExpiryDate("13/24")); // false(月份无效) console.log(isValidExpiryDate("11/00")); // false(年份过期)
可选:正则硬编码年份范围(不推荐)
如果一定要用正则直接限制年份范围(比如允许未来10年的年份),可以这样写(以2023年为例,允许23-33的年份):
const expiryRegex = /^(0[1-9]|1[0-2])\/(2[3-9]|3[0-3])$/;
但这种方式的问题是每年都需要更新正则,维护成本很高,所以更推荐前面的动态校验方案。
补充说明:大部分信用卡的有效期是到当月的最后一天,所以当输入月份等于当前月份时,我们认为是有效的,这符合行业常规规则。
内容的提问来源于stack exchange,提问作者durga siva kishore mopuru




