2010-08-10 32 views
6

Tôi có một danh sách lớn các tệp, một số tệp có ngày được nhúng trong tên tệp. Định dạng của các ngày không nhất quán và thường không đầy đủ, ví dụ: "Aug06", "Aug2006", "August 2006", "08-06", "01-08-06", "2006", "011004" vv Ngoài ra, một số tên tệp có số không liên quan trông hơi giống ngày, ví dụ "20202010".Trích xuất ngày không nhất quán được định dạng từ chuỗi (phân tích ngày, NLP)

Tóm lại, các ngày thường không đầy đủ, đôi khi không có, được định dạng không nhất quán và được nhúng trong một chuỗi với thông tin khác, ví dụ: "Báo cáo Aug06.xls".

Có bất kỳ mô-đun Perl nào có sẵn mà sẽ thực hiện công việc phong nha để đoán ngày từ chuỗi đó không? Nó không phải chính xác 100%, vì nó sẽ được xác minh bởi một người bằng tay, nhưng tôi đang cố gắng làm mọi thứ dễ dàng nhất có thể cho người đó và có hàng nghìn mục cần kiểm tra :)

Trả lời

3

Ngày :: Phân tích cú pháp chắc chắn sẽ là một phần của câu trả lời của bạn - bit hoạt động theo chuỗi ngày giống như được định dạng ngẫu nhiên và tạo ngày sử dụng thực tế.

Phần khác của vấn đề - phần còn lại của các ký tự trong tên tệp của bạn - đủ bất thường để bạn không thể tìm thấy người khác đã đóng gói mô-đun cho bạn.

Nếu không thấy nhiều dữ liệu mẫu hơn, bạn chỉ có thể đoán được, nhưng tôi sẽ bắt đầu bằng cách xác định các ứng cử viên có thể hoặc có thể là "phần ngày". Dưới đây là một ví dụ bạo lực khó chịu bằng cách sử dụng Date :: Parse (một cách tiếp cận thông minh hơn sẽ sử dụng một danh sách regex-en để thử và xác định ngày-bit - Tôi rất vui khi ghi chu kỳ CPU để không nghĩ khá khó khăn như vậy mặc dù!)

!/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

Điều này phần nào tương tự như cách tôi đã làm nó cuối cùng, nhưng tôi lâu hơn, xấu xí và đáng sợ :) Tôi sẽ để câu hỏi mở ngay bây giờ, trong trường hợp ai đó ra khỏi đó đã gặp vấn đề trước đây, nhưng có vẻ như giống như một chút của một cuộn giải pháp của riêng bạn ... –

+0

Câu trả lời của bạn về cơ bản là chính xác; dường như không có bất kỳ thư viện nào để làm điều này, bạn phải tự làm điều đó :) –

0

Date::Parse thực hiện những gì bạn muốn.

+0

Ngày :: Phân tích cú pháp không xử lý tất cả các thư rác khác trong chuỗi độc đáo, vì vậy tôi có tỷ lệ 100% không xác định bằng cách sử dụng nó; Tôi cần một cái gì đó thông minh, đủ để bỏ qua các crud và tìm một ngày. Đó là xử lý ngôn ngữ tự nhiên nhiều như phân tích ngày tháng, tôi cho là vậy. –

0

DateTime::Format::Natural trông giống như một ứng cử viên cho công việc này. Tôi không thể tự mình xác minh nhưng nó có số good reviews.

+0

Tôi đã gặp nó, nhưng giống như Ngày tháng :: Phân tích, Ngày tháng :: Manip và cộng sự dường như yêu cầu tất cả dữ liệu trong chuỗi có liên quan đến ngày, trong khi hầu hết nội dung của chuỗi của tôi chỉ là tiếng ồn (các phần khác của tên tệp). –

Các vấn đề liên quan