2010-08-10 96 views
6

我有一大堆文件,其中一些文件的日期已嵌入。日期的格式不一致且通常不完整,例如「Aug06」,「Aug2006」,「August 2006」,「08-06」,「01-08-06」,「2006」,「011004」等。除此之外,一些文件名具有不相關的數字,日期,例如「20202010」。從字符串中提取格式不一致的日期(日期解析,NLP)

簡言之,日期通常是不完整的,有時不存在,格式不一致,並且與其他信息一起嵌入到字符串中。 「Aug06.xls報告」。

是否有任何Perl模塊可用,它會做這樣一個字符串猜測日期的體面工作?它不一定是100%正確的,因爲它會通過人工驗證,但我正在儘可能爲那個人製作簡單的東西,並且有成千上萬的條目需要檢查:)

回答

3

Date :: Parse絕對會成爲你的答案的一部分 - 這是一個隨機格式化的類似日期的字符串,並將實際可用日期排除在外。

問題的其他部分 - 文件名中其餘的字符 - 非常不尋常,以至於您不太可能找到其他人爲您打包了一個模塊。

沒有看到更多您的樣本數據,它只能猜測,但我首先確定可能的或可能的「日期部分」候選人。

這是一個令人討厭的蠻力示例,使用Date :: Parse(一個更智能的方法將使用正則表達式列表來嘗試和識別日期位 - 我很高興地刻錄cpu週期以不覺得這麼難雖然!)

!/usr/bin/perl 
use strict; 
use warnings; 
use Date::Parse; 

my @files=("Report Aug06.xls", "ReportAug2006", "Report 11th September 2006.xls", 
      "Annual Report-08-06", "End-of-month Report01-08-06.xls", "Report2006"); 

# assumption - longest likely date string is something like '11th September 2006' - 19 chars 
# shortest is "2006" - 4 chars. 
# brute force all strings from 19-4 chars long at the end of the filename (less extension) 
# return the longest thing that Date::Parse recognises as a date 



foreach my $file (@files){ 
    #chop extension if there is one 
    $file=~s/\..*//; 
    for my $len (-19..-4){ 
    my $string = substr($file, $len); 
    my $time = str2time($string); 
    print "$string is a date: $time = ",scalar(localtime($time)),"\n" if $time; 
    last if $time; 
    } 
    } 
+0

這有點類似於我到底是怎麼做的,但我的時間更長,更醜陋,更可怕:)我現在不會提出這個問題,以防有人在那之前遇到問題,但似乎像一個滾動你自己的解決方案的東西...... – 2010-08-10 06:24:46

+0

你的答案基本上是正確的;似乎沒有任何圖書館這樣做,你必須自己做:) – 2010-08-13 15:18:53

0

Date::Parse做你想做的。

+0

Date :: Parse不能很好地處理字符串中的所有其他垃圾,所以我有100%未定義的速率使用它;我需要一些足夠聰明的東西來忽略殘缺並找到一個日期。我想,它和日期解析一樣是自然語言處理。 – 2010-08-10 01:33:22

0

DateTime::Format::Natural看起來像這個工作的候選人。我個人不能擔保,但它有good reviews

+0

我確實碰到過它,但像Date :: Parse,Date :: Manip等人似乎要求所有的數據在該字符串與日期相關,而我的字符串的大部分內容只是噪聲(文件名的其他部分)。 – 2010-08-10 06:25:48