python自动提取文本中的时间(包含中文日期)


Posted in Python onAugust 31, 2020

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

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']

 到此这篇关于python自动提取文本中的时间(包含中文日期)的文章就介绍到这了,更多相关python自动提取时间内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python网络编程之UDP通信实例(含服务器端、客户端、UDP广播例子)
Apr 25 Python
python中Genarator函数用法分析
Apr 08 Python
使用Django Form解决表单数据无法动态刷新的两种方法
Jul 14 Python
详解如何在Apache中运行Python WSGI应用
Jan 02 Python
python射线法判断一个点在图形区域内外
Jun 28 Python
python实现函数极小值
Jul 10 Python
python函数参数(必须参数、可变参数、关键字参数)
Aug 16 Python
pytorch 实现查看网络中的参数
Jan 06 Python
Pandas将列表(List)转换为数据框(Dataframe)
Apr 24 Python
Python json格式化打印实现过程解析
Jul 21 Python
详解如何修改python中字典的键和值
Sep 29 Python
python中time tzset()函数实例用法
Feb 18 Python
Python Selenium自动化获取页面信息的方法
Aug 31 #Python
python+requests接口自动化框架的实现
Aug 31 #Python
python如何导出微信公众号文章方法详解
Aug 31 #Python
Python生成并下载文件后端代码实例
Aug 31 #Python
python exit出错原因整理
Aug 31 #Python
Python如何将模块打包并发布
Aug 30 #Python
如何以Winsows Service方式运行JupyterLab
Aug 30 #Python
You might like
php实现随机显示图片方法汇总
2015/05/21 PHP
Zend Framework实现Zend_View集成Smarty模板系统的方法
2016/03/05 PHP
php模仿qq空间或朋友圈发布动态、评论动态、回复评论、删除动态或评论的功能(中)
2017/06/11 PHP
php实现生成带二维码图片并强制下载功能
2018/02/24 PHP
PHP中检查isset()和!empty()函数的必要性
2019/02/13 PHP
jquery取消选择select下拉框示例代码
2014/02/22 Javascript
PHP使用方法重载实现动态创建属性的get和set方法
2014/11/17 Javascript
js结合正则实现国内手机号段校验
2015/06/19 Javascript
jQuery中$this和$(this)的区别介绍(一看就懂)
2015/07/06 Javascript
Bootstrap入门书籍之(三)栅格系统
2016/02/17 Javascript
jQuery内存泄露解决办法
2016/12/13 Javascript
vue组件实现弹出框点击显示隐藏效果
2020/10/26 Javascript
JS加密插件CryptoJS实现AES加密操作示例
2018/08/16 Javascript
微信小程序实现弹出层效果
2020/05/26 Javascript
js中数组对象去重的两种方法
2019/01/18 Javascript
JS模拟浏览器实现全局搜索功能
2019/09/11 Javascript
jQuery实现轮播图源码
2019/10/23 jQuery
Nodejs技巧之Exceljs表格操作用法示例
2019/11/06 NodeJs
vue组件创建的三种方式小结
2020/02/03 Javascript
JavaScript onclick事件使用方法详解
2020/05/15 Javascript
Jquery使用each函数实现遍历及数组处理
2020/07/14 jQuery
原生js实现移动小球(碰撞检测)
2020/12/17 Javascript
如何在JavaScript中使用localStorage详情
2021/02/04 Javascript
使用IPython来操作Docker容器的入门指引
2015/04/08 Python
Django Admin实现上传图片校验功能
2016/03/06 Python
基于Django filter中用contains和icontains的区别(详解)
2017/12/12 Python
python执行系统命令后获取返回值的几种方式集合
2018/05/12 Python
关于django 数据库迁移(migrate)应该知道的一些事
2018/05/27 Python
python如何把字符串类型list转换成list
2020/02/18 Python
10个示例带你掌握python中的元组
2020/11/23 Python
HTML5网页录音和上传到服务器支持PC、Android,支持IOS微信功能
2019/04/26 HTML / CSS
HTML5实现直播间评论滚动效果的代码
2020/05/27 HTML / CSS
JD Sports丹麦:英国领先的运动时尚零售商
2020/11/24 全球购物
中学生自我评价范文
2014/02/08 职场文书
街道办残联2016年助残日活动总结
2016/04/01 职场文书
详解Go语言运用广度优先搜索走迷宫
2021/06/23 Python