有時(shí)在處理不規(guī)則數(shù)據(jù)時(shí)需要提取文本包含的時(shí)間日期。
dateutil.parser模塊可以統(tǒng)一日期字符串格式。
datefinder模塊可以在字符串中提取日期。
datefinder模塊實(shí)現(xiàn)也是用正則,功能很全 但是對(duì)中文不友好。
但是這兩個(gè)模塊都不能支持中文及一些特殊的情況;所以我用正則寫了段代碼可進(jìn)行中文日期及一些特殊的時(shí)間識(shí)別
例如:
'2012年12月12日','3小時(shí)前','在2012/12/13哈哈','時(shí)間2012-12-11 12:22:30','日期2012-13-11','測(cè)試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 # 匹配正則表達(dá)式 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 :[( '年' , '月' , '日' , '點(diǎn)' , '分' , '秒' ),( '-' , '-' ,' ',' : ',' : ',' '),(' \ / ',' \ / ',' ',' : ',' : ',' '),(' \. ',' \. ',' ',' : ',' : ',' ')]}, { 2 :[( '年' , '月' , '日' , '點(diǎn)' , '分' ),( '-' , '-' ,' ',' : ',' '),(' \ / ',' \ / ',' ',' : ',' '),(' \. ',' \. ',' ',' : ',' ')]}, { 3 :[( '年' , '月' , '日' ),( '-' , '-' ,' '),(' \ / ',' \ / ',' '),(' \. ',' \. ',' ')]}, { 4 :[( '年' , '月' , '日' ),( '-' , '-' ,' '),(' \ / ',' \ / ',' '),(' \. ',' \. ',' ')]}, { 5 :[( '月' , '日' , '點(diǎn)' , '分' , '秒' ),( '-' ,' ',' : ',' : ',' '),(' \ / ',' ',' : ',' : ',' '),(' \. ',' ',' : ',' : ',' ')]}, { 6 :[( '月' , '日' , '點(diǎn)' , '分' ),( '-' ,' ',' : ',' '),(' \ / ',' ',' : ',' '),(' \. ',' ',' : ',' ')]}, { 7 :[( '月' , '日' ),( '-' ,' '),(' \ / ',' '),(' \. ',' ')]}, { 8 :[( '點(diǎn)' , '分' , '秒' ),( ':' , ':' ,'')]}, { 9 :[( '點(diǎn)' , '分' ),( ':' ,'')]}, ] def func(parten,tp): re.search(parten,parten) parten_other = '\d+天前|\d+分鐘前|\d+小時(shí)前|\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 ): # 格式化基礎(chǔ)時(shí)間 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 ): # 構(gòu)建窮舉正則匹配公式 及提取的字符串轉(zhuǎn)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 '小時(shí)' 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小時(shí)前' , '在2012/12/13哈哈' , '時(shí)間2012-12-11 12:22:30' , '日期2012-13-11' , '測(cè)試2013.12.24' , '今天12:13' ]: res = timefinder.find_time(text) print ( 'text----' ,text) print ( 'res---' ,res) if __name__ = = '__main__' : test() |
測(cè)試運(yùn)行結(jié)果如下
text---- 2012年12月12日
res--- ['2012-12-12 00:00:00']
text---- 3小時(shí)前
res--- ['2020-04-22 21:00:00']
text---- 在2012/12/13哈哈
res--- ['2012-12-13 00:00:00']
text---- 時(shí)間2012-12-11 12:22:30
res--- ['2012-12-11 12:22:30']
text---- 日期2012-13-11
res--- None
text---- 測(cè)試2013.12.24
res--- ['2013-12-24 00:00:00']
text---- 今天12:13
res--- ['2020-04-23 12:13:00']
到此這篇關(guān)于python自動(dòng)提取文本中的時(shí)間(包含中文日期)的文章就介紹到這了,更多相關(guān)python自動(dòng)提取時(shí)間內(nèi)容請(qǐng)搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!
原文鏈接:https://www.cnblogs.com/i-love-python/p/12763063.html