修改正则表达式以匹配含完整月份且遇连字符终止的日期串
修复日期范围正则匹配问题
我需要用正则从格式各异的字符串中提取含完整月份的日期(通常是日期范围,比如February 1, 2020 - March 18, 2020或February 1st 2020 - March 18th 2020),但现有正则在处理起始日期缺少年份(与结束年份一致)的场景时出错。例如字符串January 8 - January 27, 2020会被错误匹配为["January 8 - J"],预期结果应为["January 8", "January 27, 2020"],同时还要兼容字符串前后附带其他内容的情况(比如Presented from January 8, 2020 - January 27, 2020 at such and such place)。
当前使用的正则及问题
const regex = /((\b\d{1,2}\D{0,3})?\b(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|(Nov|Dec)(?:ember)?)\D?)(\d{1,2}(st|nd|rd|th)?)?((\s*[,.\-\/]\s*)\D?)?\s*((19[0-9]\d|20\d{2})|\d{2})*/gm;
测试代码及结果
var myDateString1 = "January 8, 2020 - January 27, 2020"; // 匹配正常 var myDateString2 = "January 8 - January 27, 2020"; // 匹配异常 var dates = myDateString1.match(regex); // 返回 ["January 8, 2020","January 27, 2020"] var dates2 = myDateString2.match(regex); // 返回 ["January 8 - J"]
修改后的正则表达式
const regex = /\b(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)\D?\d{1,2}(?:st|nd|rd|th)?(?:\s*[,.]\s*(?:19\d{2}|20\d{2}))?(?=(?:\s*-\s*)|$|\s)/gm;
关键修改说明
- 增加正向预查终止匹配:通过
(?=(?:\s*-\s*)|$|\s)确保匹配到日期后,一旦遇到日期分隔连字符、字符串结尾或空格就停止当前匹配,避免把连字符和后续日期的开头部分错误纳入当前匹配结果。 - 优化匹配结构:调整为「月份 → 日期(带可选序数词后缀)→ 可选年份(带逗号/点分隔)」的明确顺序,减少模糊匹配导致的错误。
- 移除冗余模糊匹配:删掉原正则中容易引发过度匹配的
\D?滥用部分,让匹配逻辑更精准。
验证测试
// 测试缺少年份的起始日期 var dates2 = "January 8 - January 27, 2020".match(regex); // 返回 ["January 8", "January 27, 2020"] // 测试完整日期范围 var dates1 = "January 8, 2020 - January 27, 2020".match(regex); // 返回 ["January 8, 2020","January 27, 2020"] // 测试带前后内容的场景 var dates3 = "Presented from January 8, 2020 - January 27, 2020 at such and such place".match(regex); // 返回 ["January 8, 2020","January 27, 2020"] // 测试带序数词的日期 var dates4 = "February 1st 2020 - March 18th 2020".match(regex); // 返回 ["February 1st 2020", "March 18th 2020"]
内容的提问来源于stack exchange,提问作者RCNeil
相关产品推荐
相关产品推荐

