有時在處理不規則數據時需要提取文本包含的時間日期。
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