2012-07-27 62 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));