正则表达式日期时间匹配

时间:2012-03-04 22:53:18

标签: c# regex date

我正在使用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月3日或3月3日。 1990等...

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

 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的新手,所以我确信我正在做一些愚蠢的事情(比如不使用不区分大小写的选项等),所以让我知道如何改进它。

这是学习正则表达式,而不是学习如何使用库函数....

4 个答案:

答案 0 :(得分:2)

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

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

删除每个月后的.*?。这意味着以非贪婪的方式匹配任何字符。那么它的作用是检查您的下一个条件\\s+([0-9]{2,4},以便匹配

答案 1 :(得分:2)

仅解决命名月份模式:这将结合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);

编辑:不需要非回溯(残留更复杂的前瞻方法) - 删除了那部分。

答案 2 :(得分:2)

汇总了一些回答来做我想做的事情。这似乎是在自由文本中找到合理的日期。感谢所有海报。

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);

答案 3 :(得分:1)

您需要指定您正在执行此操作的语言。

通常大多数语言都会提供一种解析日期的方法,因此使用正则表达式进行验证并不是答案。