【问题标题】:Extract Date and Time from a String Using Regex使用正则表达式从字符串中提取日期和时间
【发布时间】:2018-08-30 17:27:47
【问题描述】:

我正在开发一个正则表达式,它接受所有可能的日期和时间格式以从句子中提取它们。

这是我的正则表达式:

@"(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]|(?:Jan|Mar|May|Jul|Aug|Oct|Dec)))\1|(?:(?:1|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2]|(?:Jan|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec))\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)(?:0?2|(?:Feb))\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9]|(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep))|(?:1[0-2]|(?:Oct|Nov|Dec)))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})(?:[\D]*)(?<time>\d{1,2}\:\d{2}\s(?:A|P)M)";

目前,正则表达式在句子中的任何位置提取时间时都能完美运行,但仅在日期位于句子开头时才提取日期。 此外,如果句子中有第二个日期,则正则表达式不会承认它,但如果在它与日期旁边的文本匹配之后直接有文本。

例如:

Meet me on 31/07/2019 at 3:00 PM to celebrate and then the meeting will be on 03/08/2019 at 12:00 PM.

正则表达式应该匹配:

1) 31/07/2019

2)3:00 PM

3)03/08/2019

4)12:00 PM

注意:应从句子的任何部分(开头、中间、结尾)中提取预期输出

【问题讨论】:

  • 嗨,您不应该检查日期在您的正则表达式中是否有效。您将在正则表达式之外处理 31/02,这会更容易。
  • 您有一些^$ 锚肯定会导致问题。除此之外,我建议将交替的每个部分都进行,让它工作,然后拼凑更大的正则表达式。
  • “所有可能的日期和时间格式”,这种可能性很大。可以是有效和无效格式的列表。然后逐案处理。
  • @DragandDrop 我无法分解我的代码并这样做,因为目前我的代码首先匹配然后提取匹配项。
  • @TimBiegeleisen 我已经为这段代码苦苦挣扎了好几个星期,而你帮了我很大的忙。我摆脱了锚点,代码工作了。谢谢!

标签: c# regex


【解决方案1】:

\D* + 时间模式之前的正则表达式部分匹配各种类型的日期,并且必须在添加任何其他要遵循的模式之前进行分组。即(?&lt;date&gt;DATE1_PATTERN|DATE2_PATTERN|DATEn_PATTERN)\D*(?&lt;time&gt;TIME_PATTERN)

然后,只需匹配并访问命名组:

var s = "Meet me on 31/07/2019 at 3:00 PM to celebrate and then the meeting will be on 03/08/2019 at 12:00 PM.";
var pattern = @"(?<date>(?:(?:31([-/.])(?:0?[13578]|1[02]|(?:Jan|Mar|May|Jul|Aug|Oct|Dec)))\1|(?:(?:1|30)([-/.])(?:0?[13-9]|1[0-2]|(?:Jan|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec))\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})|(?:29([-/.])(?:0?2|Feb)\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))|(?:0?[1-9]|1\d|2[0-8])([-/.])(?:(?:0?[1-9]|(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep))|(?:1[0-2]|(?:Oct|Nov|Dec)))\4(?:(?:1[6-9]|[2-9]\d)?\d{2}))\D*(?<time>\d{1,2}:\d{2}\s[AP]M)";
var result = Regex.Matches(s, pattern);
foreach (Match m in result) {
    Console.WriteLine(m.Groups["date"].Value);
    Console.WriteLine(m.Groups["time"].Value);
}

C# demo,输出:

31/07/2019
3:00 PM
03/08/2019
12:00 PM

这里是.NET regex fiddle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多