首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Python3.x从字符串中提取数据

如何使用Python3.x从字符串中提取数据
EN

Stack Overflow用户
提问于 2017-07-13 12:11:59
回答 4查看 10.5K关注 0票数 0

我需要使用Python3.4查找手机账单到期日期,我使用了dateutil.parser和datefinder,但根据我的用例没有成功。

例: sms_text =“您的Rs.72.23六月十七日的电话费( 15-07-2017 )已发送给您的regd电子邮件ID abc@xyz.com。请选中收件箱。”

代码1:

代码语言:javascript
复制
import datefinder
due_dates = datefinder.find_dates(sms_text)
for match in due_dates:
    print(match)

结果: 2017-07-17 : 00:00:00

代码2:

代码语言:javascript
复制
import dateutil.parser as dparser
due_date = dparser.parse(sms_text,fuzzy=True)
print(due_date)

结果: ValueError可能是由于文本中的多个日期

我如何从这些课文中选择到期日?日期格式不是固定的,但文本中将有两个日期:一个是生成票据的月份,另一个是按相同顺序排列的到期日。即使我得到一个正则表达式来解析文本,这也是很好的。

更多样本文本:

  1. 你好!您的手机欠费是293.72,到期日是03日。
  2. 日期为06-6月17日的219卢比账单今天到期,您的电话号码是1234567890。
  3. 日期为06-6月17日的219卢比账单将于7月5日到期,您的电话号码为1234567890。
  4. 您的运营商的固定电话/宽带ID 1234567890的日期为27-6月17日的账单已从abc@xyz.com从xyz@abc.com处发送。到期金额: 3,764.53卢比,到期日:16-7月17日。
  5. 电话号码1234567890:总到期日期: Rs 374.12,到期日:09-7月-2017年;票据交付日期:25-6月-2007,
  6. 欢迎光临!您的移动1234567890,dtd 18-6月-17日,付款到期日06-7月-17日已在abc@xyz.com上发送。
  7. 尊敬的客户,您的电话账单191.24号是在2017年6月25日至6月25日到期的。
  8. 嗨!你的电话费。560.41是在03-07-2017.
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-07-13 13:22:21

有两件事阻止datefinder正确解析您的示例:

  1. 账单金额:数字被解释为年份,所以如果它们有3或4位数字,它就会创建一个日期。
  2. datefinder定义为分隔符的字符可能会阻止找到合适的日期格式(在本例中为':')。

其想法是首先通过删除文本中阻止datefinder识别所有日期的部分来对文本进行消毒。不幸的是,这是一个尝试和错误,因为这个软件包使用的正则表达式太大,我无法深入分析。

代码语言:javascript
复制
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]'的字符串(实际上有更多的变体,但这只是为了说明)。

显然,这是一个原始的示例函数。以下是我得到的结果:

代码语言:javascript
复制
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唯一认识到的

示例:

代码语言:javascript
复制
>>> list(datefinder.find_dates('Rs 219 is due today'))
[datetime.datetime(219, 7, 13, 0, 0)]
>>> list(datefinder.find_dates('is due today'))
[]

因此,为了处理这种情况,我们可以将令牌'today'替换为当前日期,作为第一步。这将赋予以下职能:

代码语言:javascript
复制
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]

现在,所有样本的结果都很好:

代码语言:javascript
复制
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

如果需要,可以让函数返回所有日期,它们都应该是正确的。

票数 2
EN

Stack Overflow用户

发布于 2017-07-13 13:14:59

使用dateutil.parser的一个想法

代码语言:javascript
复制
from dateutil.parser import parse

for s in sms_text.split():
    try:
        print(parse(s))
    except ValueError:
        pass
票数 3
EN

Stack Overflow用户

发布于 2017-07-13 12:49:51

为什么不直接使用regex呢?如果输入字符串始终包含此子字符串,则只需执行以下操作:due on ... has been

代码语言:javascript
复制
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:
            ...
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45080248

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档