Regex日期时间匹配

本文关键字:时间 日期 Regex | 更新日期: 2023-09-27 18:26:34

我正在使用C#

string content = " 4 marco bob 53 AUSTRIA (Jan. 13, 2012) – McDonald Janruary 15, 2021 July 15, 2923   June 2 2343 7/25/23 08/22/3323";

这应该可以识别除"4 marco bob 53"之外的所有日期,这显然不是日期时间。然而,我的规则(下面)与之匹配(4 marco bob 53),我不知道如何避免匹配(或类似的例子)。

我正在尝试为所有日期时间匹配上面的字符串。我写了3条规则来匹配一些常见的日期模式。

例如:

模式f0:5/2/2012

模式f2:1900年3月3日或1990年3月或1990年5月3日等…

模式f3:2021年1月4日或2021年1月1日等…

 string f0 = "([0-9]{1,2})/([0-9]{1,2})/([0-9]{2,4})";
 string f1 = "([0-9]{1,2})''s+([jJ][aA][nN].*?|[fF][eE][bB].*?|[mM][aA][rR].*?|[aA][pP][rR].*?|[mM][aA][yY].*?|[jJ][uU][nN].*?|[jJ][uU][lL].*?|[aA][uU][gG].*?|[sS][eE][pP].*?|[oO][cC][tT].*?|[nN][oO][vV[.*?|[dD][eE][cC].*?)''s+([0-9]{2,4})";
 string f2 = "([jJ][aA][nN].*?|[fF][eE][bB].*?|[mM][aA][rR].*?|[aA][pP][rR].*?|[mM][aA][yY].*?|[jJ][uU][nN].*?|[jJ][uU][lL].*?|[aA][uU][gG].*?|[sS][eE][pP].*?|[oO][cC][tT].*?|[nN][oO][vV[.*?|[dD][eE][cC].*?)''s+([0-9]{1,2})[''s,]+([0-9]{2,4})";

我是regex的新手,所以我确信我在做一些愚蠢的事情(比如不使用不区分大小写的选项等),所以让我知道如何改进这一点。

这是为了学习regex,而不是学习如何使用库函数。。。。

Regex日期时间匹配

您的正则表达式与字符串f1匹配的原因如下:

  • 4因为([0-9]{1,2})''s+
  • mar因为[mM][aA][rR]
  • co bob因为.*?
  • 53因为''s+([0-9]{2,4}

每个月之后删除您的.*?。这意味着以非贪婪的方式匹配任何字符。这样做的目的是在''s+([0-9]{2,4}的情况下检查下一个条件是什么,这样你就可以匹配

聚合了一些发布的答案来做我想做的事情。这似乎可以很好地在自由文本中找到日期。感谢所有的海报。

string f0 = "(?:(''d{1,2})/(''d{1,2})/(''d{2,4}))";
string f1 = "(?:(''s''d{1,2})''s+(jan(?:uary){0,1}''.{0,1}|feb(?:ruary){0,1}''.{0,1}|mar(?:ch){0,1}''.{0,1}|apr(?:il){0,1}''.{0,1}|may''.{0,1}|jun(?:e){0,1}''.{0,1}|jul(?:y){0,1}''.{0,1}|aug(?:ust){0,1}''.{0,1}|sep(?:tember){0,1}''.{0,1}|oct(?:ober){0,1}''.{0,1}|nov(?:ember){0,1}''.{0,1}|dec(?:ember){0,1}''.{0,1})''s+(''d{2,4}))";
 string f2 = "(?:(jan(?:uary){0,1}''.{0,1}|feb(?:ruary){0,1}''.{0,1}|mar(?:ch){0,1}''.{0,1}|apr(?:il){0,1}''.{0,1}|may''.{0,1}|jun(?:e){0,1}''.{0,1}|jul(?:y){0,1}''.{0,1}|aug(?:ust){0,1}''.{0,1}|sep(?:tember){0,1}''.{0,1}|oct(?:ober){0,1}''.{0,1}|nov(?:ember){0,1}''.{0,1}|dec(?:ember){0,1}''.{0,1})''s+([0-9]{1,2})[''s,]+(''d{2,4}))";
MatchCollection mc = Regex.Matches(content, f0 + "|" + f1 + "|" + f2, RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);

仅寻址命名的月份模式:这结合了2和3,并且需要再执行一步来修复此处的最后一个匹配:89 Febuary 12, 2099,但如果您希望这样做,则可以很容易地分离:

    string input = " 4 marco bob 53 AUSTRIA (Jan. 13, 2012) – McDonald January 15, 2021 July 15, 2923   June 2 2343 7/25/23 08/22/3323 7 jul 2098 0 Jan 0 fake stuff 89 Febuary 12, 2099 it is a greedy";
    var pattern =
    @"('d'd?'s)? (?# greedily gather preceding dd)
    (jan(uary)?|feb(uary)?|mar(ch)?|apr(il)?|may|june?|july?|aug(ust)?|sep(tember)?|nov(ember)?|dec(ember)?)
    '.?'s?                
    ('d'd?'b,?'s*)? (?# optional day part)
    'd'd('d'd)?";           
    var matches = Regex.Matches(input, pattern, RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
    string result = string.Empty;
    for (int i = 0; i < matches.Count; i++)
    {
        result += "match " + i + ",value:" + matches[i].Value + "'n";
    }   
    Console.WriteLine(result);

edit:不回溯是不必要的(更复杂的前瞻性方法的残余)-删除了那个部分

您需要指定使用哪种语言进行此操作。

一般来说,大多数语言都会提供一种解析日期的方法,所以自己使用regex进行验证并不是解决问题的方法。