Извлечь непоследовательно отформатированную дату из строки (синтаксический анализ даты, НЛП)

У меня есть большой список файлов, некоторые из которых имеют даты, встроенные в имя файла. Формат дат является непоследовательным и часто неполным, например. "Aug06", "Aug2006", "Август 2006", "08-06", "01-08-06", "2006", "011004" и т.д. Кроме того, некоторые имена файлов имеют несвязанные номера, которые выглядят как даты, например "20202010".

Короче говоря, даты, как правило, неполные, иногда не существуют, несогласованно отформатированы и встроены в строку с другой информацией, например. "Report Aug06.xls".

Есть ли доступные модули Perl, которые будут делать достойную работу по угадыванию даты из такой строки? Он не должен быть на 100% правильным, поскольку он будет проверен человеком вручную, но я стараюсь сделать все как можно проще для этого человека, и есть тысячи записей для проверки:)

3 ответа

Date:: Parse определенно будет частью вашего ответа - бит, который выдает случайную форматированную датуподобную строку и делает фактическую полезную дату из нее.

Другая часть вашей проблемы - остальные символы в ваших именах файлов - достаточно необычна, что вряд ли вы обнаружите, что кто-то еще упаковал модуль для вас.

Не видя больше ваших выборочных данных, на самом деле можно только догадываться, но я бы начал с определения возможных или вероятных кандидатов "date section".

Вот скверный пример грубой силы, использующий Date:: Parse (более разумный подход использовал бы список regex-en, чтобы попытаться определить даты-бит - я с удовольствием записываю циклы процессора, чтобы не думать так сильно, хотя!)

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


DateTime::Format::Natural выглядит кандидатом на эту работу. Я не могу ручаться за него лично, но хорошие отзывы.


Date:: Parse делает то, что вы хотите.

licensed under cc by-sa 3.0 with attribution.