Solo una pista: comienza y termina con un dígito. Dejame pensar sobre eso. Aunque, regex puede ser tu amigo allí.
Hamish Grubijan
Respuestas:
82
Si la fecha se da en una forma fija, simplemente puede usar una expresión regular para extraer la fecha y "datetime.datetime.strptime" para analizar la fecha:
import re
from datetime import datetime
match = re.search(r'\d{4}-\d{2}-\d{2}', text)
date = datetime.strptime(match.group(), '%Y-%m-%d').date()
De lo contrario, si la fecha se da de forma arbitraria, no podrá extraerla fácilmente.
¿Qué pasa si está en formato europeo, como 20/01/1980 que significa "20 de enero de 1980"? ¿Qué pasa si los meses / días / años quedan fuera del rango razonable?
Hamish Grubijan
@lunaryorn En la primera declaración, ¿"re" se refiere a la cadena donde estamos buscando nuestro patrón deseado?
vishal
@ vishal.k Se refiere a la incorporada en el remódulo, es decir, import re.
lunaryorn
En caso de que alguien más cometiera el mismo error: necesita hacerlo en from datetime import datetimelugar deimport datetime
In [1]: import dateutil.parser as dparser
In [18]: dparser.parse("monkey 2010-07-10 love banana",fuzzy=True)
Out[18]: datetime.datetime(2010, 7, 10, 0, 0)
Las fechas no válidas generan un ValueError:
In [19]: dparser.parse("monkey 2010-07-32 love banana",fuzzy=True)
# ValueError: day is out of range for month
Puede reconocer fechas en muchos formatos:
In [20]: dparser.parse("monkey 20/01/1980 love banana",fuzzy=True)
Out[20]: datetime.datetime(1980, 1, 20, 0, 0)
Tenga en cuenta que adivina si la fecha es ambigua:
In [23]: dparser.parse("monkey 10/01/1980 love banana",fuzzy=True)
Out[23]: datetime.datetime(1980, 10, 1, 0, 0)
Pero la forma en que analiza las fechas ambiguas es personalizable:
In [21]: dparser.parse("monkey 10/01/1980 love banana",fuzzy=True, dayfirst=True)
Out[21]: datetime.datetime(1980, 1, 10, 0, 0)
@Hamish: Si hay dos fechas (como en el caso de "monkey 10/01/1980 love 7/10/2010 banana"), puede generar un ValueError, o (como en el caso de "monkey 10/01/1980 love 2010-07-10 banana") puede malinterpretar la segunda fecha como indicando horas, minutos, segundos o zona horaria. fuzzy=Truele da licencia para adivinar.
unutbu
1
@unutbu str = "Por flufie  · 14 de octubre de 2010 a las 11:22 pm  · 26 respuestas" Al usar dateutil obtengo "ValueError: la hora debe estar en 0..23"
saravanan
¿Qué pasa si hay más de una fecha en el texto?
alvas
1
@alvas: La parsefunción puede generar una excepción (incluso si fuzzy=True), o con fuzzy=True, puede devolver la primera fecha o una mezcla compuesta por partes de ambas fechas. Entonces, en realidad, parsesolo debería llamarse en una cadena que contenga una fecha.
unutbu
1
@Kailegh: Sí, sería posible deducir los índices usando fuzzy_with_tokens = True . Si desea más aclaraciones, inicie una nueva pregunta.
unutbu
27
Para extraer la fecha de una cadena en Python; el mejor módulo disponible es el módulo de buscador de fechas .
Puede usarlo en su proyecto de Python siguiendo los sencillos pasos que se indican a continuación.
Paso 1: Instale el paquete datefinder
pip install datefinder
Paso 2: Úselo en su proyecto
import datefinder
input_string = "monkey 2010-07-10 love banana"# a generator will be returned by the datefinder module. I'm typecasting it to a list. Please read the note of caution provided at the bottom.
matches = list(datefinder.find_dates(input_string))
iflen(matches) > 0:
# date returned will be a datetime.datetime object. here we are only using the first match.
date = matches[0]
print date
else:
print'No dates found'
nota: si espera una gran cantidad de coincidencias; entonces, el encasillado a la lista no será una forma recomendada, ya que tendrá una gran sobrecarga de rendimiento.
Descubrí que la datefindercoincidencia de fechas ambiguas es mejor que python-dateutildevolver solo dos fechas posibles de una publicación de blog de medium.com al azar en lugar de cinco. No estoy seguro de cómo se maneja diferentes lugares, sin embargo ...
CpILL
Esto es bastante bueno, excepto que de alguna manera no funciona cuando hay dos puntos (:) antes de la cadena de fecha: string = "Assessment Date: 17-May-2017 at 13:31"list(datefinder.find_dates(string.lower()))#[]string = "Assessment Date 17-May-2017 at 13:31"list(datefinder.find_dates(string.lower()))#[datetime.datetime(2017, 5, 17, 13, 31)]
Narahari BM
Estoy de acuerdo en que el buscador de fechas es mucho mejor que el analizador de fechas para texto ambiguo
Jay Jung
2
Con Pygrok, puede definir extensiones abstractas para la sintaxis de expresiones regulares.
Los patrones personalizados se pueden incluir en su expresión regular en el formato %{PATTERN_NAME}.
También puede crear una etiqueta para ese patrón, separando con dos puntos: %s{PATTERN_NAME:matched_string}. Si el patrón coincide, el valor se devolverá como parte del diccionario resultante (p. Ej.result.get('matched_string') . )
Por ejemplo:
from pygrok import Grok
input_string = 'monkey 2010-07-10 love banana'
date_pattern = '%{YEAR:year}-%{MONTHNUM:month}-%{MONTHDAY:day}'
grok = Grok(date_pattern)
print(grok.match(input_string))
El valor resultante será un diccionario:
{'month': '07', 'day': '10', 'year': '2010'}
Si date_pattern no existe en input_string, el valor de retorno será None. Por el contrario, si su patrón no tiene etiquetas, devolverá un diccionario vacío{}
También puede probar el módulo dateparser , que puede ser más lento que el datefinder en texto libre, pero que debería cubrir más casos y formatos de fecha potenciales, así como una cantidad significativa de idiomas.
Si conoce la posición del objeto de fecha en la cadena (por ejemplo, en un archivo de registro), puede usar .split () [índice] para extraer la fecha sin conocer completamente el formato.
Por ejemplo:
>>> string = 'monkey 2010-07-10 love banana'>>> date = string.split()[1]
>>> date
'2010-07-10'
Respuestas:
Si la fecha se da en una forma fija, simplemente puede usar una expresión regular para extraer la fecha y "datetime.datetime.strptime" para analizar la fecha:
import re from datetime import datetime match = re.search(r'\d{4}-\d{2}-\d{2}', text) date = datetime.strptime(match.group(), '%Y-%m-%d').date()
De lo contrario, si la fecha se da de forma arbitraria, no podrá extraerla fácilmente.
fuente
re
módulo, es decir,import re
.from datetime import datetime
lugar deimport datetime
Usando python-dateutil :
In [1]: import dateutil.parser as dparser In [18]: dparser.parse("monkey 2010-07-10 love banana",fuzzy=True) Out[18]: datetime.datetime(2010, 7, 10, 0, 0)
Las fechas no válidas generan un
ValueError
:In [19]: dparser.parse("monkey 2010-07-32 love banana",fuzzy=True) # ValueError: day is out of range for month
Puede reconocer fechas en muchos formatos:
In [20]: dparser.parse("monkey 20/01/1980 love banana",fuzzy=True) Out[20]: datetime.datetime(1980, 1, 20, 0, 0)
Tenga en cuenta que adivina si la fecha es ambigua:
In [23]: dparser.parse("monkey 10/01/1980 love banana",fuzzy=True) Out[23]: datetime.datetime(1980, 10, 1, 0, 0)
Pero la forma en que analiza las fechas ambiguas es personalizable:
In [21]: dparser.parse("monkey 10/01/1980 love banana",fuzzy=True, dayfirst=True) Out[21]: datetime.datetime(1980, 1, 10, 0, 0)
fuente
"monkey 10/01/1980 love 7/10/2010 banana"
), puede generar un ValueError, o (como en el caso de"monkey 10/01/1980 love 2010-07-10 banana"
) puede malinterpretar la segunda fecha como indicando horas, minutos, segundos o zona horaria.fuzzy=True
le da licencia para adivinar.parse
función puede generar una excepción (incluso sifuzzy=True
), o confuzzy=True
, puede devolver la primera fecha o una mezcla compuesta por partes de ambas fechas. Entonces, en realidad,parse
solo debería llamarse en una cadena que contenga una fecha.Para extraer la fecha de una cadena en Python; el mejor módulo disponible es el módulo de buscador de fechas .
Puede usarlo en su proyecto de Python siguiendo los sencillos pasos que se indican a continuación.
Paso 1: Instale el paquete datefinder
Paso 2: Úselo en su proyecto
import datefinder input_string = "monkey 2010-07-10 love banana" # a generator will be returned by the datefinder module. I'm typecasting it to a list. Please read the note of caution provided at the bottom. matches = list(datefinder.find_dates(input_string)) if len(matches) > 0: # date returned will be a datetime.datetime object. here we are only using the first match. date = matches[0] print date else: print 'No dates found'
nota: si espera una gran cantidad de coincidencias; entonces, el encasillado a la lista no será una forma recomendada, ya que tendrá una gran sobrecarga de rendimiento.
fuente
datefinder
coincidencia de fechas ambiguas es mejor quepython-dateutil
devolver solo dos fechas posibles de una publicación de blog de medium.com al azar en lugar de cinco. No estoy seguro de cómo se maneja diferentes lugares, sin embargo ...string = "Assessment Date: 17-May-2017 at 13:31"
list(datefinder.find_dates(string.lower()))
#[]
string = "Assessment Date 17-May-2017 at 13:31"
list(datefinder.find_dates(string.lower()))
#[datetime.datetime(2017, 5, 17, 13, 31)]
Con Pygrok, puede definir extensiones abstractas para la sintaxis de expresiones regulares.
Los patrones personalizados se pueden incluir en su expresión regular en el formato
%{PATTERN_NAME}
.También puede crear una etiqueta para ese patrón, separando con dos puntos:
%s{PATTERN_NAME:matched_string}
. Si el patrón coincide, el valor se devolverá como parte del diccionario resultante (p. Ej.result.get('matched_string')
. )Por ejemplo:
from pygrok import Grok input_string = 'monkey 2010-07-10 love banana' date_pattern = '%{YEAR:year}-%{MONTHNUM:month}-%{MONTHDAY:day}' grok = Grok(date_pattern) print(grok.match(input_string))
El valor resultante será un diccionario:
{'month': '07', 'day': '10', 'year': '2010'}
Si date_pattern no existe en input_string, el valor de retorno será
None
. Por el contrario, si su patrón no tiene etiquetas, devolverá un diccionario vacío{}
Referencias:
fuente
También puede probar el módulo dateparser , que puede ser más lento que el datefinder en texto libre, pero que debería cubrir más casos y formatos de fecha potenciales, así como una cantidad significativa de idiomas.
fuente
Si conoce la posición del objeto de fecha en la cadena (por ejemplo, en un archivo de registro), puede usar .split () [índice] para extraer la fecha sin conocer completamente el formato.
Por ejemplo:
>>> string = 'monkey 2010-07-10 love banana' >>> date = string.split()[1] >>> date '2010-07-10'
fuente