C#从字符串中提取具有多种格式的多个日期

时间:2019-02-21 09:04:16

标签: c# regex text-extraction

我不确定这是否是问这个问题的最佳地点,因此请事先道歉。

我需要从一个字符串中提取多个日期。但是,日期格式可能因字符串而异(单个字符串中两个日期的格式应相同),并且日期周围的文本也可能不同。我无法控制字符串,但是它们都将按英国的日期和月份顺序排列。字符串示例包括但不限于

  

从1960年3月1日到2235年3月1日

     

从1/3/1960开始到1/3/2235结束的时间段

     

从1.3.1960开始到1.3.2235结束

我目前的想法是在字符串上运行多个RegEx,每种可能的格式使用一个RegEx,并具有一些逻辑来限制要使用的RegEx(例如,如果字符串包含'/',我将运行那些RegEx变体首先使用那个)。

但是,我希望有一种更好的方法来实现这一目标。我发现它将运行的环境可能无法调用Web服务。因此,如果可能的话,我正在寻找一个独立的解决方案。

2 个答案:

答案 0 :(得分:0)

尝试使用正则表达式:\b(?:(?:31(\/|-| |\.)(?:0?[13578]|1[02]|(?:Jan|January|Mar|March|May|Jul|July|Aug|August|Oct|October|Dec|December)))\1|(?:(?:29|30)(\/|-| |\.)(?:0?[1,3-9]|1[0-2]|(?:Jan|January|Mar|March|Apr|April|May|Jun|June|Jul|July|Aug|August|Sep|September|Oct|October|Nov|November|Dec|December))\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})\b|\b(?:29(\/|-| |\.)(?:0?2|(?:Feb|February))\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))\b|\b(?:0?[1-9]|1\d|2[0-8])(\/|-| |\.)(?:(?:0?[1-9]|(?:Jan|January|Feb|February|Mar|March|Apr|April|May|Jun|June|Jul|July|Aug|August|Sep|September))|(?:1[0-2]|(?:Oct|October|Nov|November|Dec|December)))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})\b

Demo

答案 1 :(得分:0)

您可以使用两个正则表达式和一个替换表达式,然后使用DateTime.ParseExact来转换DateTime对象中的日期。也许是这样的:

string[] lines = { "From 1 March 1960 To 1 March 2235", 
                   "For a period starting 1/3/1960 and ending 1/3/2235", 
                   "Starting 1.3.1960 and ending 1.3.2235", 
                   "Just some string with no dates in it" };
foreach (string line in lines) {

    Console.ForegroundColor = ConsoleColor.Yellow;
    Console.WriteLine(System.Environment.NewLine + line);
    Console.ResetColor();

    if (Regex.IsMatch(line, @"(\d{1,2}\s+\w+\s+\d{4})"))
    {
        Regex regexObj = new Regex(@"(\d{1,2}\s+\w+\s+\d{4})");
        Match matchResults = regexObj.Match(line);
        while (matchResults.Success)
        {
            DateTime dte = DateTime.ParseExact(matchResults.Value, "d MMMM yyyy", CultureInfo.GetCultureInfo("en-GB"));
            Console.WriteLine(dte.ToShortDateString());
            matchResults = matchResults.NextMatch();
        }
    }
    else if (Regex.IsMatch(line, @"(\d{1,2}[./]\d{1,2}[./]\d{4})"))
    {
        Regex regexObj = new Regex(@"(\d{1,2}[./]\d{1,2}[./]\d{4})");
        Match matchResults = regexObj.Match(line);
        while (matchResults.Success)
        {
            DateTime dte = DateTime.ParseExact(matchResults.Value.Replace(".","/"), "d/M/yyyy", CultureInfo.GetCultureInfo("en-GB"));
            Console.WriteLine(dte.ToShortDateString());
            matchResults = matchResults.NextMatch();
        }
    }
    else { Console.WriteLine("No valid date found."); }

}

以上返回

From 1 March 1960 To 1 March 2235
1/3/1960
1/3/2235

For a period starting 1/3/1960 and ending 1/3/2235
1/3/1960
1/3/2235

Starting 1.3.1960 and ending 1.3.2235
1/3/1960
1/3/2235

Just some string with no dates in it
No valid date found.