有时在处理不规则数据时需要提取文本包含的时间日期。
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'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
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自动提取时间内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://www.cnblogs.com/i-love-python/p/12763063.html