Просто подсказка: начинается и заканчивается цифрой. Дай мне подумать об этом. Хотя регулярное выражение может быть там вашим другом.
Hamish Grubijan
Ответы:
82
Если дата указана в фиксированной форме, вы можете просто использовать регулярное выражение для извлечения даты и «datetime.datetime.strptime» для анализа даты:
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()
В противном случае, если дата указана в произвольной форме, вы не сможете легко ее извлечь.
Что, если это будет в европейском формате, например, 20.01.1980, что означает «20 января 1980 года»? Что, если месяцы / дни / годы выходят за пределы разумного диапазона?
Hamish Grubijan
@lunaryorn В первом операторе относится ли "re" к строке, в которой мы ищем желаемый шаблон?
Вишал 05
@ vishal.k Это относится к встроенному в reмодуль, то есть import re.
lunaryorn 05
На случай, если кто-то другой совершил ту же ошибку: вам нужно from datetime import datetimeвместоimport 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)
Недействительные даты вызывают ValueError:
In [19]: dparser.parse("monkey 2010-07-32 love banana",fuzzy=True)
# ValueError: day is out of range for month
Он может распознавать даты во многих форматах:
In [20]: dparser.parse("monkey 20/01/1980 love banana",fuzzy=True)
Out[20]: datetime.datetime(1980, 1, 20, 0, 0)
Обратите внимание, что он делает предположение, если дата неоднозначна:
In [23]: dparser.parse("monkey 10/01/1980 love banana",fuzzy=True)
Out[23]: datetime.datetime(1980, 10, 1, 0, 0)
Но способ анализа неоднозначных дат можно настроить:
In [21]: dparser.parse("monkey 10/01/1980 love banana",fuzzy=True, dayfirst=True)
Out[21]: datetime.datetime(1980, 1, 10, 0, 0)
@Hamish: если есть две даты (как в случае "monkey 10/01/1980 love 7/10/2010 banana"), это может вызвать ошибку ValueError или (как в случае "monkey 10/01/1980 love 2010-07-10 banana") оно может неверно истолковать вторую дату как обозначающую часы, минуты, секунды или часовой пояс. fuzzy=Trueдает ему право гадать.
unutbu
1
@unutbu str = "Автор flufie · 14 октября 2010 г., 23:22 · 26 ответов" Используя dateutil, я получаю "ValueError: час должен быть в 0..23"
saravanan
что будет, если в тексте более 1 даты?
alvas
1
@alvas: parseфункция может вызвать исключение (даже если fuzzy=True) или с fuzzy=True, она может вернуть первую дату или мешанину, состоящую из частей обеих дат. Так что на самом деле parseследует вызывать только строку, содержащую одну дату.
unutbu 09
1
@Kailegh: Да, можно было бы вывести индексы, используя fuzzy_with_tokens = True . Если вам нужны дополнительные пояснения, задайте новый вопрос.
unutbu 01
27
Для извлечения даты из строки в Python; лучший доступный модуль - это модуль поиска даты .
Вы можете использовать его в своем проекте Python, выполнив простые шаги, указанные ниже.
Шаг 1. Установите пакет datefinder
pip install datefinder
Шаг 2: используйте его в своем проекте
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'
Примечание: если вы ожидаете большого количества совпадений; то приведение типов к списку не будет рекомендованным способом, так как это приведет к большим накладным расходам производительности.
Я обнаружил, что datefinderпереданное неоднозначное сопоставление дат лучше, чем python-dateutilвозвращение только двух возможных дат из случайного сообщения в блоге medium.com вместо пяти. Однако не знаю, как он обрабатывает разные локации ...
CpILL
Это неплохо, но почему-то не работает, когда перед строкой даты стоит двоеточие (:): 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)]
Нарахари Б.М.
согласен с тем, что datefinder намного лучше, чем dateparser для неоднозначного текста
Джей Чон
2
Используя Pygrok, вы можете определять абстрактные расширения синтаксиса регулярных выражений.
Пользовательские шаблоны могут быть включены в ваше регулярное выражение в формате %{PATTERN_NAME}.
Вы также можете создать метку для этого шаблона, разделив двоеточием: %s{PATTERN_NAME:matched_string} . Если шаблон совпадает, значение будет возвращено как часть полученного словаря (например,result.get('matched_string') )
Например:
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))
Полученное значение будет словарем:
{'month': '07', 'day': '10', 'year': '2010'}
Если шаблон date_pattern не существует в input_string, возвращаемое значение будет None. Напротив, если ваш шаблон не имеет меток, он вернет пустой словарь.{}
Вы также можете попробовать модуль dateparser , который может быть медленнее, чем datefinder для произвольного текста, но который должен охватывать больше потенциальных случаев и форматов даты, а также значительное количество языков.
Если вам известно положение объекта даты в строке (например, в файле журнала), вы можете использовать .split () [index] для извлечения даты, не зная полностью ее формат.
Например:
>>> string = 'monkey 2010-07-10 love banana'>>> date = string.split()[1]
>>> date
'2010-07-10'
Ответы:
Если дата указана в фиксированной форме, вы можете просто использовать регулярное выражение для извлечения даты и «datetime.datetime.strptime» для анализа даты:
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()
В противном случае, если дата указана в произвольной форме, вы не сможете легко ее извлечь.
источник
re
модуль, то естьimport re
.from datetime import datetime
вместоimport datetime
Используя 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)
Недействительные даты вызывают
ValueError
:In [19]: dparser.parse("monkey 2010-07-32 love banana",fuzzy=True) # ValueError: day is out of range for month
Он может распознавать даты во многих форматах:
In [20]: dparser.parse("monkey 20/01/1980 love banana",fuzzy=True) Out[20]: datetime.datetime(1980, 1, 20, 0, 0)
Обратите внимание, что он делает предположение, если дата неоднозначна:
In [23]: dparser.parse("monkey 10/01/1980 love banana",fuzzy=True) Out[23]: datetime.datetime(1980, 10, 1, 0, 0)
Но способ анализа неоднозначных дат можно настроить:
In [21]: dparser.parse("monkey 10/01/1980 love banana",fuzzy=True, dayfirst=True) Out[21]: datetime.datetime(1980, 1, 10, 0, 0)
источник
"monkey 10/01/1980 love 7/10/2010 banana"
), это может вызвать ошибку ValueError или (как в случае"monkey 10/01/1980 love 2010-07-10 banana"
) оно может неверно истолковать вторую дату как обозначающую часы, минуты, секунды или часовой пояс.fuzzy=True
дает ему право гадать.parse
функция может вызвать исключение (даже еслиfuzzy=True
) или сfuzzy=True
, она может вернуть первую дату или мешанину, состоящую из частей обеих дат. Так что на самом делеparse
следует вызывать только строку, содержащую одну дату.Для извлечения даты из строки в Python; лучший доступный модуль - это модуль поиска даты .
Вы можете использовать его в своем проекте Python, выполнив простые шаги, указанные ниже.
Шаг 1. Установите пакет datefinder
Шаг 2: используйте его в своем проекте
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'
Примечание: если вы ожидаете большого количества совпадений; то приведение типов к списку не будет рекомендованным способом, так как это приведет к большим накладным расходам производительности.
источник
datefinder
переданное неоднозначное сопоставление дат лучше, чемpython-dateutil
возвращение только двух возможных дат из случайного сообщения в блоге medium.com вместо пяти. Однако не знаю, как он обрабатывает разные локации ...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)]
Используя Pygrok, вы можете определять абстрактные расширения синтаксиса регулярных выражений.
Пользовательские шаблоны могут быть включены в ваше регулярное выражение в формате
%{PATTERN_NAME}
.Вы также можете создать метку для этого шаблона, разделив двоеточием:
%s{PATTERN_NAME:matched_string}
. Если шаблон совпадает, значение будет возвращено как часть полученного словаря (например,result.get('matched_string')
)Например:
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))
Полученное значение будет словарем:
{'month': '07', 'day': '10', 'year': '2010'}
Если шаблон date_pattern не существует в input_string, возвращаемое значение будет
None
. Напротив, если ваш шаблон не имеет меток, он вернет пустой словарь.{}
Рекомендации:
источник
Вы также можете попробовать модуль dateparser , который может быть медленнее, чем datefinder для произвольного текста, но который должен охватывать больше потенциальных случаев и форматов даты, а также значительное количество языков.
источник
Если вам известно положение объекта даты в строке (например, в файле журнала), вы можете использовать .split () [index] для извлечения даты, не зная полностью ее формат.
Например:
>>> string = 'monkey 2010-07-10 love banana' >>> date = string.split()[1] >>> date '2010-07-10'
источник