如何在句子中使用NLP和正则表达式查找日期
有没有人能给我推荐一些方法,用来在Python中找到和解析日期(无论是什么格式,比如“Aug06”、“Aug2006”、“August 2 2008”、“19th August 2006”、“08-06”、“01-08-06”)。
我看到过这个问题,但它是用Perl写的……从字符串中提取格式不一致的日期(日期解析,自然语言处理)
任何建议都很有帮助。
3 个回答
0
对于你的需求,一个不错的选择是“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"))
3
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:
...
7
这段代码可以找到你例句中的所有日期:
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
,但这显然是无法解析的。