修改正则表达式以匹配日期与序号“st”,“nd”,“rd”,“th”

时间:2010-01-22 16:43:44

标签: regex date ordinals

如何修改下面的正则表达式以匹配日期部分的日期?这个正则表达式匹配“2003年1月1日| 2004年2月29日| 3202年11月02日”但我也需要它匹配:“2003年1月1日| 2004年2月29日| 11月02日,3202 | 2010年3月3日”

^(?:(((Jan(uary)?|Ma(r(ch)?|y)|Jul(y)?|Aug(ust)?|Oct(ober)?|Dec(ember)?)\ 31)|((Jan(uary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sept|Nov|Dec)(ember)?)\ (0?[1-9]|([12]\d)|30))|(Feb(ruary)?\ (0?[1-9]|1\d|2[0-8]|(29(?=,\ ((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))))\,\ ((1[6-9]|[2-9]\d)\d{2}))

谢谢。

2 个答案:

答案 0 :(得分:5)

这取决于您的使用案例,但为了实用主义,您可能只需匹配任何匹配的内容:
(1)任何月份名称或缩写;
(2)空格;
(3)任何一个或两个数字;
(4)空格;
(5)任何st,nd,rd,th;
(6)空格或逗号+可选空格;
(7)任何四位数字;

我不确定你的匹配对象,但如果我有Jan 35nd,3001,我想我宁愿现在抓住它并在以后使其无效而不是跳过它就在开始的时候。

此外,根据您的数据集,请考虑区分大小写问题和常见的国际英语变体,例如1 Jan 20041st Jan, 2004January, 2004等。

添加了换行符

^(?:j(?:an(?:uary)?|un(?:e)?|ul(?:y)?)?|feb(?:ruary)?|ma(?:r(?:ch)?|y)
|a(?:pr(?:il)?|ug(?:ust)?)|sep(?:t|tember)?|oct(?:ober)?|(?:nov|dec)(?:ember)?)  
\s+\d{1,2}(?:st|nd|rd|th)?(?:\s+|,\s*)\d{4}\b

更实用(和可读),除非你有一个非常奇怪的数据集,否则允许在公共前缀之后的任何内容:

(?:jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[a-z]*?\s+\d{1,2}(?:[a-z]{2})?(?:\s+|,\s*)\d{4}\b

这匹配octagenarianism 99xx, 0000吗?是。这可能是个问题吗?我对此表示怀疑。

答案 1 :(得分:2)

那个正则表达式太过分了。使用相当于strptime()的语言会更好。但是,下面的正则表达式将与序数匹配:

^(?:(((Jan(uary)?|Ma(r(ch)?|y)|Jul(y)?|Aug(ust)?|Oct(ober)?|Dec(ember)?)\ 31(st)?)|((Jan(uary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sept|Nov|Dec)(ember)?)\ (0?[1-9]|([12]\d)|30))(st|nd|rd|th)?|(Feb(ruary)?\ (0?[1-9]|1\d|2[0-8]|(29(th)?(?=,\ ((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))(st|nd|rd|th)?))\,\ ((1[6-9]|[2-9]\d)\d{2}))

请注意,它也会匹配“20nd”之类的内容,但在实际数据中遇到这种情况的可能性太低,无法在大多数情况下打扰照顾。