JavaScript中用正则重排日期部件时格式与数值长度不匹配如何解决
问题根源
你原代码的核心问题是默认格式占位符的长度等于日期对应部分的长度,但d、m这类1位占位符允许对应1或2位数字,当实际值为2位时,后续所有占位符的计算索引都会整体偏移,最终导致提取值错误。
解决方案
不要硬按占位符索引截取,而是先把日期格式模板转换为对应正则表达式,通过分隔符自动定位各部分的边界,再从捕获组提取年月日值,适配所有占位符规则:
function parseDate(dateStr, format) { // 转义格式中的正则特殊字符,避免匹配异常 const escapedFormat = format.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); const captureKeys = []; // 替换占位符为对应匹配规则,同时记录捕获顺序 const regexStr = escapedFormat .replace(/y{4}/g, () => { captureKeys.push('year'); return '(\\d{4})'; }) .replace(/y{2}/g, () => { captureKeys.push('year'); return '(\\d{2})'; }) .replace(/m{2}/g, () => { captureKeys.push('month'); return '(\\d{2})'; }) .replace(/m{1}/g, () => { captureKeys.push('month'); return '(\\d{1,2})'; }) .replace(/d{2}/g, () => { captureKeys.push('day'); return '(\\d{2})'; }) .replace(/d{1}/g, () => { captureKeys.push('day'); return '(\\d{1,2})'; }); const dateRegex = new RegExp(`^${regexStr}$`); const matchResult = dateStr.match(dateRegex); if (!matchResult) return null; const parsed = {}; captureKeys.forEach((key, index) => { parsed[key] = matchResult[index + 1]; }); // 可选:两位年份自动补全世纪,可根据业务调整阈值 if (parsed.year?.length === 2) { parsed.year = Number(parsed.year) >= 50 ? `19${parsed.year}` : `20${parsed.year}`; } return parsed; } // 测试你的场景 const result = parseDate('15.10.2021', 'd.m.yyyy'); console.log(result.year); // 输出 2021 console.log(result.month); // 输出 10 console.log(result.day); // 输出 15
该方案完全适配你提到的占位符规则:
"d" 日期数字,单日无前置零
"dd" 日期数字,单日补前置零
"m" 月份数字,单月无前置零
"mm" 月份数字,单月补前置零
"yy" 两位年份
"yyyy" 四位年份
内容的提问来源于stack exchange,提问作者Jesper
相关产品推荐
相关产品推荐

