1

如何修改下面的正则表达式以匹配日期与日期部分的序数?此正则表达式匹配“2003 年 1 月 1 日 | 2004 年 2 月 29 日 | 3202 年 11 月 2 日”,但我还需要它来匹配:“2003 年 1 月 1 日 | 2004 年 2 月 29 日 | 3202 年 11 月 2 日 | 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}))

谢谢你。

4

2 回答 2

5

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

我不确定你匹配的是什么,但如果我有Jan 35nd,3001,我想我宁愿现在捕获它并稍后使其无效,而不是一开始就跳过它。

此外,根据您的数据集,考虑区分大小写问题和常见的国际英语变体,例如1 Jan 2004or 1st Jan, 2004orJanuary, 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吗?是的。这可能是一个问题吗?我对此表示怀疑。

于 2010-01-22T18:33:40.980 回答
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”之类的内容,但在实际数据中遇到这种情况的可能性太低,在大多数情况下都无法关心。

于 2010-01-22T16:56:44.967 回答