2012-07-27 63 views
0

我正在使用此模式从文本文件中提取确认日期并将它们转换为日期对象(请参阅我的文章Extract/convert date from string in MS Access)。正则表达式提取负向预测日期

目前的模式,看起来像一个日期的所有字符串相匹配,但可能无法确定日(总是通过确认之前),而且,可能没有完整的最新信息(没有AMPM )。

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

我想要的方式去寻找日期在文本文件中的区段以分号开头,以分号结尾。此外,为了适当地转换时间,模式应该只在末尾匹配AM或PM。我该如何限制这个模式并添加额外的AM或PM标准?

任何人都可以帮忙吗?

回答

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中。

2

为了匹配字符串的末尾,请在正则表达式的末尾使用$。要匹配整个短语“Confirmed by <someone> on <date>”,请使用纯文本(请记住,纯文本也可以在正则表达式中使用 - 如果不使用特殊字符,匹配器将逐字匹配您的查询)。您需要使用负先行排除整个words.So也许是这样的:

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

,这将使你,匹配以“以确认”开头的字符串,然后除了什么“on”,后面跟着你捕捉的日期,以及字符串的结尾。

编辑:负前瞻部分是棘手的,看看下面的详细参考答案:

A regular expression to exclude a word/string

+0

我试图用[GSKinner的Reg Exr工具](http://gskinner.com/RegExr/?)在源文本中使用此模式,但它似乎没有捕获日期。对于日期模式,下面提到的模式(\ d +/\ d +/\ d + \ s + \ d +:\ d +:\ d + \ s +(?: AM | PM));很好地工作。但仍然无法获得负面预测工作。 – regulus 2012-07-27 21:58:43

+0

我将负向视图中的引号更改为转义空格并删除了方括号,这有帮助吗? – maxko87 2012-07-27 22:04:05

0

试试这个:

(\d+/\d+/\d+\s+\d+:\d+:\d+\s+(?:AM|PM)); 
+0

这将很好地匹配源文本中的所有日期。任何想法如何限制以'确认'开始并以';'结尾的细分市场? – regulus 2012-07-27 21:42:29

0

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

Confirmed by.*?(\d+/\d+/\d+\s+\d+:\d+:\d+\s+(?:AM|PM));