2010-08-10 15 views
6

Tengo una gran lista de archivos, algunos de los cuales tienen fechas incrustadas en el nombre del archivo. El formato de las fechas es inconsistente y a menudo incompleto, p. "Aug06", "Aug2006", "August 2006", "08-06", "01-08-06", "2006", "011004" etc. Además de eso, algunos nombres de archivos tienen números no relacionados que se parecen un poco a fechas, por ejemplo "20202010".Extraer de manera irregular la fecha de la cadena (fecha de análisis, NLP)

En resumen, las fechas son normalmente incompletas, a veces no están allí, están formateadas de manera irregular y están incrustadas en una cadena con otra información, p. "Informe Aug06.xls".

¿Hay algún módulo Perl disponible que haga un trabajo decente adivinando la fecha de una cadena? No tiene que ser 100% correcto, ya que será verificado por un humano manualmente, pero estoy tratando de hacer las cosas lo más fáciles posible para esa persona y hay miles de entradas para verificar :)

Respuesta

3

Fecha :: Parse definitivamente va a ser parte de su respuesta, el bit que funciona como una cadena con fecha aleatoria formateada y hacer una fecha utilizable real de ella.

La otra parte de su problema - el resto de los caracteres en sus nombres de archivo - es lo suficientemente inusual que es poco probable que encuentre a alguien más que haya empaquetado un módulo para usted.

Sin ver más de sus datos de muestra, solo es posible adivinar, pero comenzaría por identificar candidatos posibles o posibles de "sección de fecha".

Aquí hay un desagradable ejemplo de fuerza bruta usando Date :: Parse (un enfoque más inteligente usaría una lista de regex-en para tratar de identificar fechas-bits) Estoy feliz de grabar ciclos de CPU para no pensar tan duro sin embargo!)

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

Esto es algo similar a cómo lo hice al final, pero el mío es mucho más largo, más feo y aterrador :) Dejaré la pregunta abierta por ahora, en caso de que alguien haya encontrado el problema antes, pero parece como un poco de rollo tu propia solución ... –

+0

Tu respuesta es esencialmente correcta; no parece haber ninguna biblioteca para hacer esto, tienes que hacerlo tú mismo :) –

0

Date::Parse hace lo que quiere.

+0

Fecha :: Parse no maneja todos los demás elementos no deseados de la cadena, así que tengo una tasa 100% indefinida usándolo; Necesito algo lo suficientemente inteligente como para ignorar la porquería y encontrar una fecha. Es un procesamiento de lenguaje natural como el análisis de la fecha, supongo. –

0

DateTime::Format::Natural parece un candidato para este trabajo. No puedo responder personalmente pero tiene good reviews.

+0

Lo encontré, pero como Date :: Parse, Date :: Manip et al parece requerir que todos los datos en la cadena es relevante para la fecha, mientras que la mayoría del contenido de mis cadenas son solo ruido (otras partes del nombre del archivo). –

Cuestiones relacionadas