0

我正在使用此模式从文本文件中提取确认日期并将它们转换为日期对象(请参阅我的帖子从 MS Access 中的字符串中提取/转换日期)。

当前模式匹配所有看起来像日期的字符串,但可能不是确认日期(始终以 Confirmed by 开头),而且可能没有完整的日期信息(例如noAMPM)。

 Pattern: (\d+/\d+/\d+\s+\d+:\d+:\d+\s+\w+|\d+-\w+-\d+\s+\d+:\d+:\d+)

示例文本:

WHEN COMPARED WITH RESULT OF 7/13/12 09:06:42  NO SIGNIFICANT 
CHANGE; Confirmed by SMITH, MD, JOHN (2242) on 7/14/2012 3:46:21 PM;

上述模式匹配以下内容:

WHEN COMPARED WITH RESULT OF 7/13/12 09:06:42  NO SIGNIFICANT 
                             ^^^^^^^^^^^^^^^^^^^^
CHANGE; Confirmed by SMITH, MD, JOHN (2242) on 7/14/2012 3:46:21 PM;
                                               ^^^^^^^^^^^^^^^^^^^^

我希望该模式在以 Confirmed by 开头并以分号结尾的文本文件段中查找日期。此外,为了正确转换时间,模式应该只匹配最后的 AM 或 PM。如何将模式限制到此段并添加额外的 AM 或 PM 条件?

任何人都可以帮忙吗?

4

4 回答 4

2

为了匹配字符串$的结尾,请在正则表达式的末尾使用。要匹配整个短语“ Confirmed by <someone> on <date>”,请使用纯文本(请记住,纯文本也可以在正则表达式中使用——如果您不使用特殊字符,匹配器将逐字匹配您的查询)。您需要使用否定前瞻来排除整个单词。所以可能是这样的:

Confirmed by (?!\ on\ )(\d+/\d+/\d+\s+\d+:\d+:\d+\s+\w+|\d+-\w+-\d+\s+\d+:\d+:\d+)$

这将允许您匹配以“Confirmed by”开头的字符串,然后是除“on”之外的任何内容,然后是您捕获的日期和字符串的结尾。

编辑:负前瞻部分很棘手,请查看下面的答案以获取更多参考:

排除单词/字符串的正则表达式

于 2012-07-27T21:30:10.990 回答
1

我认为这里不需要向前看,无论是正面的还是负面的。这适用于您的示例字符串:

Confirmed by [^;]*(\d+/\d+/\d+\s+\d+:\d+:\d+(?:\s+(?:AM|PM))?|\d+-\w+-\d+\s+\d+:\d+:\d+);

有效地划分了序列与其结束分号之间的[^;]*匹配。Confirmed by(我假设分号将始终存在。)

+(?:\s+(?:AM|PM))?使 AM/PM 及其前导空格成为可选。

实际日期将存储在捕获组 #1 中。

于 2012-07-28T11:30:59.807 回答
0

试试这个:

(\d+/\d+/\d+\s+\d+:\d+:\d+\s+(?:AM|PM));
于 2012-07-27T21:31:05.327 回答
0

最简单的答案通常是一个足够好的解决方案。通过关闭默认的贪婪行为(使用问号:).*?,正则表达式将尝试找到与模式匹配的最短匹配。一个模式永远不会多次匹配同一个字符串,这意味着每个模式Confirmed by只能与一个日期相结合,在这种情况下是下一个日期。

Confirmed by.*?(\d+/\d+/\d+\s+\d+:\d+:\d+\s+(?:AM|PM));
于 2012-07-27T22:33:58.827 回答