我需要使用Python 3.4从SMS中找出电话帐单截止日期我已经使用了dateutil.parser和datefinder,但根据我的用例没有成功。
示例:sms_text ="您的电话帐单已经发送到您的regd电子邮件地址abc@xyz.com,该电话帐单是17月20日到期的Rs.72.23的Jun 17。请检查收件箱"
代码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可能是因为文本中有多个日期
如何从此类文本中选择截止日期?日期格式不固定,但文本中将有2个日期:一个是生成账单的月份,另一个是截止日期,顺序相同。即使我得到一个正则表达式来解析文本,也会很棒。
更多示例文本:
答案 0 :(得分:2)
使用var dt = $("#myTable").DataTable({
dom: "lfrtip" // i = info, indicates DOM order
paging: false // to turn off default is true
});
的想法:
dateutil.parser
答案 1 :(得分:0)
为什么不使用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:
...
答案 2 :(得分:0)
以短信作为示例提供:
sms_text = "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"
可以在regex模块中使用pythons构建来匹配字符串的'due on'和'has been'部分。
import re
sms_text = "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"
due_date = re.split('due on', re.split('has been', sms_text)[0])[1]
print(due_date)
结果:15-07-2017
使用此示例时,日期格式无关紧要,但重要的是将字符串拆分的单词保持一致。
答案 3 :(得分:0)
有两件事阻止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
如果需要,可以让函数返回所有日期,它们都应该是正确的。