我需要使用Python3.4查找手机账单到期日期,我使用了dateutil.parser和datefinder,但根据我的用例没有成功。
例: sms_text =“您的Rs.72.23六月十七日的电话费( 15-07-2017 )已发送给您的regd电子邮件ID abc@xyz.com。请选中收件箱。”
代码1:
import datefinder
due_dates = datefinder.find_dates(sms_text)
for match in due_dates:
print(match)结果: 2017-07-17 : 00:00:00
代码2:
import dateutil.parser as dparser
due_date = dparser.parse(sms_text,fuzzy=True)
print(due_date)结果: ValueError可能是由于文本中的多个日期
我如何从这些课文中选择到期日?日期格式不是固定的,但文本中将有两个日期:一个是生成票据的月份,另一个是按相同顺序排列的到期日。即使我得到一个正则表达式来解析文本,这也是很好的。
更多样本文本:
发布于 2017-07-13 13:22:21
有两件事阻止datefinder正确解析您的示例:
datefinder定义为分隔符的字符可能会阻止找到合适的日期格式(在本例中为':')。其想法是首先通过删除文本中阻止datefinder识别所有日期的部分来对文本进行消毒。不幸的是,这是一个尝试和错误,因为这个软件包使用的正则表达式太大,我无法深入分析。
def extract_duedate(text):
# Sanitize the text for datefinder by replacing the tricky parts
# with a non delimiter character
text = re.sub(':|Rs[\d,\. ]+', '|', text, flags=re.IGNORECASE)
return list(datefinder.find_dates(text))[-1]Rs[\d,\. ]+将移除账单金额,因此它不会被误认为是日期的一部分。它将匹配表单'Rs[.][ ][12,]345[.67]'的字符串(实际上有更多的变体,但这只是为了说明)。
显然,这是一个原始的示例函数。以下是我得到的结果:
1 : 2017-07-03 00:00:00
2 : 2017-06-06 00:00:00 # Wrong result: first date instead of today
3 : 2017-07-05 00:00:00
4 : 2017-07-16 00:00:00
5 : 2017-06-25 00:00:00
6 : 2017-07-06 00:00:00
7 : 2017-06-25 00:00:00
8 : 2017-03-07 00:00:00示例2中有一个问题:“今天”不是datefinder唯一认识到的
示例:
>>> list(datefinder.find_dates('Rs 219 is due today'))
[datetime.datetime(219, 7, 13, 0, 0)]
>>> list(datefinder.find_dates('is due today'))
[]因此,为了处理这种情况,我们可以将令牌'today'替换为当前日期,作为第一步。这将赋予以下职能:
def extract_duedate(text):
if 'today' in text:
text = text.replace('today', datetime.date.today().isoformat())
# Sanitize the text for datefinder by replacing the tricky parts
# with a non delimiter character
text = re.sub(':|Rs[\d,\. ]+', '|', text, flags=re.IGNORECASE)
return list(datefinder.find_dates(text))[-1]现在,所有样本的结果都很好:
1 : 2017-07-03 00:00:00
2 : 2017-07-18 00:00:00 # Well, this is the date of my test
3 : 2017-07-05 00:00:00
4 : 2017-07-16 00:00:00
5 : 2017-06-25 00:00:00
6 : 2017-07-06 00:00:00
7 : 2017-06-25 00:00:00
8 : 2017-03-07 00:00:00如果需要,可以让函数返回所有日期,它们都应该是正确的。
发布于 2017-07-13 13:14:59
使用dateutil.parser的一个想法
from dateutil.parser import parse
for s in sms_text.split():
try:
print(parse(s))
except ValueError:
pass发布于 2017-07-13 12:49:51
为什么不直接使用regex呢?如果输入字符串始终包含此子字符串,则只需执行以下操作:due on ... has been:
import re
from datetime import datetime
string = """Your phone bill for Jun'17 of Rs.72.23 due on 15-07-2017 has been
sent to your regd email ID abc@xyz.com. Pls check Inbox"""
match_obj = re.search(r'due on (.*) has been', string)
if match_obj:
date_str = match_obj.group(1)
else:
print "No match!!"
try:
# DD-MM-YYYY
print datetime.strptime(date_str, "%d-%m-%Y")
except ValueError:
# try another format
try:
print datetime.strptime(date_str, "%Y-%m-%d")
except ValueError:
try:
print datetime.strptime(date_str, "%m-%d")
except ValueError:
...https://stackoverflow.com/questions/45080248
复制相似问题