Как найти даты в предложении, используя NLP, RegEx в Python
Может кто-нибудь предложить мне какой-нибудь способ поиска и анализа дат (в любом формате: "Aug06", "Aug2006", "2 августа 2008", "19 августа 2006", "08-06", "01-08-06") в питоне.
Я сталкивался с этим вопросом, но он есть в perl... Извлекать неправильно отформатированную дату из строки (разбор даты, NLP)
Любое предложение будет полезно.
2 ответа
Это находит все даты в вашем примере предложения:
for match in re.finditer(
r"""(?ix) # case-insensitive, verbose regex
\b # match a word boundary
(?: # match the following three times:
(?: # either
\d+ # a number,
(?:\.|st|nd|rd|th)* # followed by a dot, st, nd, rd, or th (optional)
| # or a month name
(?:(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z]*)
)
[\s./-]* # followed by a date separator or whitespace (optional)
){3} # do this three times
\b # and end at a word boundary.""",
subject):
# match start: match.start()
# match end (exclusive): match.end()
# matched text: match.group()
Это определенно не идеально и может пропустить некоторые даты (особенно если они не на английском языке - 21. Mai 2006
потерпит неудачу, а также 4ème décembre 1999
), и чтобы соответствовать ерунде, как August Augst Aug
, но поскольку в ваших примерах почти все необязательно, на уровне регулярных выражений вы мало что можете сделать.
Следующим шагом будет подача всех совпадений в анализатор и проверка, сможет ли он проанализировать их в разумную дату.
Регулярное выражение не может правильно интерпретировать контекст. Вообразите (глупый) текст как You'll find it in box 21. August 3rd will be the shipping date.
Будет соответствовать 21. August 3rd
который конечно не может быть проанализирован.
from dateutil import parser
texts = ["Aug06", "Aug2006", "August 2 2008", "19th August 2006", "08-06", "01-08-06"]
for text in texts:
print text, parser.parse(text)
Aug06 2010-08-06 00:00:00
Aug2006 2006-08-28 00:00:00
August 2 2008 2008-08-02 00:00:00
19th August 2006 2006-08-19 00:00:00
08-06 2010-08-06 00:00:00
01-08-06 2006-01-08 00:00:00
И если вы хотите найти эти даты в более длинном тексте, то попробуйте найти группы чисел и месяцев и попытаться передать их этому анализатору. Он выдаст исключение, если текст не похож на дату.
months = ['January', 'February',...]
months.extend([mon[:3] for mon in months])
# search for numeric dates:
/[\d \-]+/
# search for dates:
for word in sentence.split():
if word in months:
...
Хороший вариант для вашего случая использования - dateutil.parser, его так просто использовать!
from dateutil.parser import parse
test_cases = ['15th of April 2020', '06/20/95', '8/2/69', '1/25/2011', '9/3/2002', '4-13-82', 'Mar-02-2009', 'Jan 20, 1974',
'March 20, 1990', 'Dec. 21, 2001', 'May 25 2009', '01 Mar 2002', '2 April 2003', '20 Aug. 2004',
'20 November, 1993', 'Aug 10th, 1994', 'Sept 1st, 2005', 'Feb. 22nd, 1988', 'Sept 2002', 'Sep 2002',
'December, 1998', 'Oct. 2000', '6/2008', '12/2001', '1998', '2002']
for date_string in test_cases:
print(date_string, parse(date_string).strftime("%Y%m%d"))