热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Python自动提取文本中的时间(包含中文日期)及特殊时间识别方法

本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。

有时在处理不规则数据时需要提取文本包含的时间日期。

dateutil.parser模块可以统一日期字符串格式。

datefinder模块可以在字符串中提取日期。

datefinder模块实现也是用正则,功能很全 但是对中文不友好。

但是这两个模块都不能支持中文及一些特殊的情况;所以我用正则写了段代码可进行中文日期及一些特殊的时间识别

例如:

'2012年12月12日','3小时前','在2012/12/13哈哈','时间2012-12-11 12:22:30','日期2012-13-11','测试2013.12.24','今天12:13'

import re
import chardet
from datetime import datetime,timedelta
# 匹配正则表达式
matchs = {
1:(r'\d{4}%s\d{1,2}%s\d{1,2}%s \d{1,2}%s\d{1,2}%s\d{1,2}%s','%%Y%s%%m%s%%d%s %%H%s%%M%s%%S%s'),
2:(r'\d{4}%s\d{1,2}%s\d{1,2}%s \d{1,2}%s\d{1,2}%s','%%Y%s%%m%s%%d%s %%H%s%%M%s'),
3:(r'\d{4}%s\d{1,2}%s\d{1,2}%s','%%Y%s%%m%s%%d%s'),
4:(r'\d{2}%s\d{1,2}%s\d{1,2}%s','%%y%s%%m%s%%d%s'),

# 没有年份
5:(r'\d{1,2}%s\d{1,2}%s \d{1,2}%s\d{1,2}%s\d{1,2}%s','%%m%s%%d%s %%H%s%%M%s%%S%s'),
6:(r'\d{1,2}%s\d{1,2}%s \d{1,2}%s\d{1,2}%s','%%m%s%%d%s %%H%s%%M%s'),
7:(r'\d{1,2}%s\d{1,2}%s','%%m%s%%d%s'),

# 没有年月日
8:(r'\d{1,2}%s\d{1,2}%s\d{1,2}%s','%%H%s%%M%s%%S%s'),
9:(r'\d{1,2}%s\d{1,2}%s','%%H%s%%M%s'),
}
# 正则中的%s分割
splits = [
{1:[('年','月','日','点','分','秒'),('-','-','',':',':',''),('\/','\/','',':',':',''),('\.','\.','',':',':','')]},
{2:[('年','月','日','点','分'),('-','-','',':',''),('\/','\/','',':',''),('\.','\.','',':','')]},
{3:[('年','月','日'),('-','-',''),('\/','\/',''),('\.','\.','')]},
{4:[('年','月','日'),('-','-',''),('\/','\/',''),('\.','\.','')]},
{5:[('月','日','点','分','秒'),('-','',':',':',''),('\/','',':',':',''),('\.','',':',':','')]},
{6:[('月','日','点','分'),('-','',':',''),('\/','',':',''),('\.','',':','')]},
{7:[('月','日'),('-',''),('\/',''),('\.','')]},
{8:[('点','分','秒'),(':',':','')]},
{9:[('点','分'),(':','')]},
]
def func(parten,tp):
re.search(parten,parten)

parten_other = '\d+天前|\d+分钟前|\d+小时前|\d+秒前'
class TimeFinder(object):
def __init__(self,base_date=None):
self.base_date = base_date
self.match_item = []

self.init_args()
self.init_match_item()
def init_args(self):
# 格式化基础时间
if not self.base_date:
self.base_date = datetime.now()
if self.base_date and not isinstance(self.base_date,datetime):
try:
self.base_date = datetime.strptime(self.base_date,'%Y-%m-%d %H:%M:%S')
except Exception as e:
raise 'type of base_date must be str of%Y-%m-%d %H:%M:%S or datetime'
def init_match_item(self):
# 构建穷举正则匹配公式 及提取的字符串转datetime格式映射
for item in splits:
for num,value in item.items():
match = matchs[num]
for sp in value:
tmp = []
for m in match:
tmp.append(m%sp)
self.match_item.append(tuple(tmp))
def get_time_other(self,text):
m = re.search('\d+',text)
if not m:
return None
num = int(m.group())
if '天' in text:
return self.base_date - timedelta(days=num)
elif '小时' in text:
return self.base_date - timedelta(hours=num)
elif '分钟' in text:
return self.base_date - timedelta(minutes=num)
elif '秒' in text:
return self.base_date - timedelta(secOnds=num)
return None
def find_time(self,text):
# 格式化text为str类型
if isinstance(text,bytes):
encoding =chardet.detect(text)['encoding']
text = text.decode(encoding)
res = []
parten = '|'.join([x[0] for x in self.match_item])
parten = parten+ '|' +parten_other
match_list = re.findall(parten,text)
if not match_list:
return None
for match in match_list:
for item in self.match_item:
try:
date = datetime.strptime(match,item[1].replace('\\',''))
if date.year==1900:
date = date.replace(year=self.base_date.year)
if date.mOnth==1:
date = date.replace(mOnth=self.base_date.month)
if date.day==1:
date = date.replace(day=self.base_date.day)
res.append(datetime.strftime(date,'%Y-%m-%d %H:%M:%S'))
break
except Exception as e:
date = self.get_time_other(match)
if date:
res.append(datetime.strftime(date,'%Y-%m-%d %H:%M:%S'))
break
if not res:
return None
return res
def test():
timefinder =TimeFinder(base_date='2020-04-23 00:00:00')
for text in ['2012年12月12日','3小时前','在2012/12/13哈哈','时间2012-12-11 12:22:30','日期2012-13-11','测试2013.12.24','今天12:13']:
res = timefinder.find_time(text)
print('text----',text)
print('res---',res)
if __name__ == '__main__':
test()

测试运行结果如下

text---- 2012年12月12日
res--- ['2012-12-12 00:00:00']
text---- 3小时前
res--- ['2020-04-22 21:00:00']
text---- 在2012/12/13哈哈
res--- ['2012-12-13 00:00:00']
text---- 时间2012-12-11 12:22:30
res--- ['2012-12-11 12:22:30']
text---- 日期2012-13-11
res--- None
text---- 测试2013.12.24
res--- ['2013-12-24 00:00:00']
text---- 今天12:13
res--- ['2020-04-23 12:13:00']


推荐阅读
  • 本文介绍了机器学习手册中关于日期和时区操作的重要性以及其在实际应用中的作用。文章以一个故事为背景,描述了学童们面对老先生的教导时的反应,以及上官如在这个过程中的表现。同时,文章也提到了顾慎为对上官如的恨意以及他们之间的矛盾源于早年的结局。最后,文章强调了日期和时区操作在机器学习中的重要性,并指出了其在实际应用中的作用和意义。 ... [详细]
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
  • 使用Spring AOP实现切面编程的步骤和注意事项
    本文介绍了使用Spring AOP实现切面编程的步骤和注意事项。首先解释了@EnableAspectJAutoProxy、@Aspect、@Pointcut等注解的作用,并介绍了实现AOP功能的方法。然后详细介绍了创建切面、编写测试代码的过程,并展示了测试结果。接着讲解了关于环绕通知的使用方法,并修改了FirstTangent类以添加环绕通知方法。最后介绍了利用AOP拦截注解的方法,只需修改全局切入点即可实现。使用Spring AOP进行切面编程可以方便地实现对代码的增强和拦截。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • 标题: ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • MPLS VP恩 后门链路shamlink实验及配置步骤
    本文介绍了MPLS VP恩 后门链路shamlink的实验步骤及配置过程,包括拓扑、CE1、PE1、P1、P2、PE2和CE2的配置。详细讲解了shamlink实验的目的和操作步骤,帮助读者理解和实践该技术。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • 本文介绍了在MFC下利用C++和MFC的特性动态创建窗口的方法,包括继承现有的MFC类并加以改造、插入工具栏和状态栏对象的声明等。同时还提到了窗口销毁的处理方法。本文详细介绍了实现方法并给出了相关注意事项。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • 十大经典排序算法动图演示+Python实现
    本文介绍了十大经典排序算法的原理、演示和Python实现。排序算法分为内部排序和外部排序,常见的内部排序算法有插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。文章还解释了时间复杂度和稳定性的概念,并提供了相关的名词解释。 ... [详细]
  • 超级简单加解密工具的方案和功能
    本文介绍了一个超级简单的加解密工具的方案和功能。该工具可以读取文件头,并根据特定长度进行加密,加密后将加密部分写入源文件。同时,该工具也支持解密操作。加密和解密过程是可逆的。本文还提到了一些相关的功能和使用方法,并给出了Python代码示例。 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有