所有通过.NET DateTime.Parse的字符串的正则表达式

所有通过.NET DateTime.Parse的字符串的正则表达式,.net,regex,datetime,.net,Regex,Datetime,在你告诉我这是很多正则表达式之前-我知道。不要求任何人写任何正则表达式!你知道有没有人已经做过这个正则表达式了吗 这将返回所有模式:CultureInfo.CurrentCulture.DateTimeFormat.GetAllDateTimePatterns() 但这份清单并非100%准确。有些模式不解析(yy/mm/dd),有些模式解析未列出。引用en-US泛型DateTime.Parse 我所做的是分解模式,并尝试为每个模式编写正则表达式 (^|\s)(3[01]|[12]\d|0?[1-

在你告诉我这是很多正则表达式之前-我知道。不要求任何人写任何正则表达式!你知道有没有人已经做过这个正则表达式了吗

这将返回所有模式:CultureInfo.CurrentCulture.DateTimeFormat.GetAllDateTimePatterns() 但这份清单并非100%准确。有些模式不解析(yy/mm/dd),有些模式解析未列出。引用en-US泛型DateTime.Parse

我所做的是分解模式,并尝试为每个模式编写正则表达式

(^|\s)(3[01]|[12]\d|0?[1-9])\s+(January|February|March|April|May|June|July|August|September|October|November|December),\s?(19|20)?\d\d(\s+(0?\d|1\d|2[0-4]):[0-6]\d(:[0-6]\d)?(\s+([AP]M|GMT|[+-]\d\d:?\d\d))?)?
        //dd MMMM, yyyy                dddd, dd MMMM, yyyy
        //dd MMMM, yyyy h:mm tt        dddd, dd MMMM, yyyy h:mm tt
        //dd MMMM, yyyy hh:mm tt       dddd, dd MMMM, yyyy h:mm:ss tt
        //dd MMMM, yyyy h:mm:ss tt     dddd, dd MMMM, yyyy hh:mm tt
        //dd MMMM, yyyy hh:mm:ss tt    dddd, dd MMMM, yyyy hh:mm:ss tt
        //dd MMMM, yyyy H:mm           dddd, dd MMMM, yyyy H:mm
        //dd MMMM, yyyy HH:mm          dddd, dd MMMM, yyyy HH:mm
        //dd MMMM, yyyy H:mm:ss        dddd, dd MMMM, yyyy H:mm:ss
        //dd MMMM, yyyy HH:mm:ss       dddd, dd MMMM, yyyy HH:mm:ss

(^|\s)(3[01]|[12]\d|0?[1-9])(/|-)(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)(/|-)\d\d(\s+(0?\d|1\d|2[0-4]):[0-6]\d(:[0-6]\d)?(\s+([AP]M|GMT|[+-]\d\d:?\d\d))?)?
        //dd-MMM-yy 
        //dd-MMM-yy h:mm tt 
        //dd-MMM-yy h:mm:ss tt  
        //dd-MMM-yy hh:mm tt    
        //dd-MMM-yy hh:mm:ss tt 
        //dd-MMM-yy H:mm    
        //dd-MMM-yy HH:mm   
        //dd-MMM-yy H:mm:ss 
        //dd-MMM-yy HH:mm:ss

(^|\s)(January|February|March|April|May|June|July|August|September|October|November|December)\s(3[01]|[12]\d|0?[1-9])(,\s?|\s)(19|20)?\d\d(\s+(0?\d|1\d|2[0-4]):[0-6]\d(:[0-6]\d)?(\s+([AP]M|GMT|[+-]\d\d:?\d\d))?)?
        //MMMM dd, yyyy             dddd, MMMM dd, yyyy
        //MMMM dd, yyyy h:mm tt     dddd, MMMM dd, yyyy h:mm tt
        //MMMM dd, yyyy h:mm:ss tt  dddd, MMMM dd, yyyy h:mm:ss tt
        //MMMM dd, yyyy hh:mm tt    dddd, MMMM dd, yyyy hh:mm tt
        //MMMM dd, yyyy hh:mm:ss tt dddd, MMMM dd, yyyy hh:mm:ss tt
        //MMMM dd, yyyy H:mm        dddd, MMMM dd, yyyy HH:mm       
        //MMMM dd, yyyy H:mm:ss     dddd, MMMM dd, yyyy H:mm:ss     
        //MMMM dd, yyyy HH:mm       dddd, MMMM dd, yyyy HH:mm:ss        
        //MMMM dd, yyyy HH:mm:ss

(^|\s)(19|20)\d\d(/|-)(1[0-2]|0?\d)(/|-)(3[01]|[12]\d|0?[1-9])(\s+(0?\d|1\d|2[0-4]):[0-6]\d(:[0-6]\d)?(\s+([AP]M|GMT|[+-]\d\d:?\d\d))?)?
        /yy/MM/dd   yyyy-MM-dd      
        //yy/MM/dd h:mm tt      yyyy-MM-dd h:mm tt      
        //yy/MM/dd hh:mm tt     yyyy-MM-dd hh:mm tt     
        //yy/MM/dd h:mm:ss tt   yyyy-MM-dd h:mm:ss tt       
        //yy/MM/dd hh:mm:ss tt  yyyy-MM-dd hh:mm:ss tt      
        //yy/MM/dd H:mm         yyyy-MM-dd H:mm     
        //yy/MM/dd HH:mm        yyyy-MM-dd HH:mm        
        //yy/MM/dd H:mm:ss      yyyy-MM-dd H:mm:ss      
        //yy/MM/dd HH:mm:ss     yyyy-MM-dd HH:mm:ss 

(^|\s)(3[01]|[12]\d|0?[1-9])(/|-|/.)(1[0-2]|0?\d)(/|-|/.)(19|20)?\d\d(\s+(0?\d|1\d|2[0-4]):[0-6]\d(:[0-6]\d)?(\s+([AP]M|GMT|[+-]\d\d:?\d\d))?)?
        //fr-FR         
        //dd.MM.yy              dd/MM/yy            dd-MM-yy            dd/MM/yyyy
        //dd.MM.yy H:mm         dd/MM/yy H:mm       dd-MM-yy H:mm       dd/MM/yyyy H:mm
        //dd.MM.yy H:mm:ss      dd/MM/yy H:mm:ss    dd-MM-yy H:mm:ss    dd/MM/yyyy H:mm:ss
        //dd.MM.yy HH' h 'mm    dd/MM/yy HH' h 'mm  dd-MM-yy HH' h 'mm  dd/MM/yyyy HH' h 'mm
        //dd.MM.yy HH.mm        dd/MM/yy HH.mm      dd-MM-yy HH.mm      dd/MM/yyyy HH.mm
        //dd.MM.yy HH:mm        dd/MM/yy HH:mm      dd-MM-yy HH:mm      dd/MM/yyyy HH:mm
        //dd.MM.yy HH:mm:ss     dd/MM/yy HH:mm:ss   dd-MM-yy HH:mm:ss   dd/MM/yyyy HH:mm:ss

我要冒险,假设你不解析那天的名字,只要剩下的日期和时间是匹配的。。。毕竟,一旦解析了日期,就可以重新生成日期的名称(这需要额外的表达式复杂性,所以我决定将其排除在外。也就是说,我有一个表达式,它似乎可以很好地查找
GetAllDateTimePatterns
返回的所有日期格式,以及其他一些可能出现的格式(不确定是否需要这些…):

(请注意,它与日期名称不匹配,但与日期匹配)

这是一个表达:

(?i)((3[01]|[12]\d|0?[1-9]|\d{4})([\s/.-]))?\b(1[0-2]|0?\d|(jan|febr?)(uary)?|ma(r(ch)?|y)|a(pr(il)?|ug(ust)?)|(sept?|oct|nov|dec)((em|o)ber)?|ju(ne?|ly?))\b(\3|\s)(((?(2)|3[01])|[12]\d|0?[1-9])(?(2)\d\d\b|\b,?\s+(20|19)?\d\d))?\s+(\d+([:.]\d+)+)?
我相信这是相当好的(我认为准确度和人类快速浏览文本一样高),但显然远远不够完美,因此需要在找到软匹配后进行真正的解析。如果可能,可以通过从搜索中排除部分消息来提高整体搜索的效率-如果要查找的日期都在标头中,则只针对标头运行表达式


让我知道它是否工作得足够好,或者您是否发现了任何边缘情况,我会看看是否可以修改它。

为什么您认为正则表达式是正确的方法?为什么不使用
DateTime.TryParse
?@JonSkeet,因为我需要解析字符串。正如我所说的,我有来自电子邮件和其他本机文件的文本。我需要从文本中提取(最佳)潜在的日期时间,匹配就可以了?如果有,那么就包括在内。对于电子邮件解析,它的结构要复杂得多,可以足够聪明,只解析一行和某些行。我仍然没有真正理解你。你是想从电子邮件中获取所有日期和时间,还是只从特定的邮件头获取日期和时间?@JonSkeet不幸的是,我没有邮件头。我有一个textual摘录。不是所有日期,而是具体日期。我需要顶部日期和任何转发日期或回复日期。知道哪些行将(或应该)有转发或回复日期,但不在行中的任何位置。我无法控制日期格式。目的是为电子邮件线程创建索引。在非电子邮件文本上,只需提取任何日期作为日期索引(只是一个搜索选项).你能发一封或两封电子邮件吗?你真的在寻找任何可能的日期/时间模式吗?如果你能限制你正在寻找的模式,那会容易得多。我会尝试一下。如果一周中的某一天没有它,日期仍然有效,那么我想我同意。它可以做什么呢?它可以识别一个无效的日期,这是一个好方法ing。这不是问题,但有些日期是外来的,这就是我用来设置适当文化的。你不需要处理“GMT”,事实证明这很重要,因为没有它就可以解析本地时间。他们不使用0000表示GMT。但看起来仍然不错。我会测试它。我现在正在编译一个所有主要格式的列表,并将在中发布这个question@Blam-不确定你是否还在寻找这个答案,但我一直在时不时地研究一个表达,我希望我会发布soonI更喜欢我在问题中发布的答案,但你的答案帮助我达到了目的。
(?i)((3[01]|[12]\d|0?[1-9]|\d{4})([\s/.-]))?\b(1[0-2]|0?\d|(jan|febr?)(uary)?|ma(r(ch)?|y)|a(pr(il)?|ug(ust)?)|(sept?|oct|nov|dec)((em|o)ber)?|ju(ne?|ly?))\b(\3|\s)(((?(2)|3[01])|[12]\d|0?[1-9])(?(2)\d\d\b|\b,?\s+(20|19)?\d\d))?\s+(\d+([:.]\d+)+)?