|
import re
|
|
import requests
|
|
import datetime
|
|
import operator
|
|
from typing import *
|
|
from dateutil.relativedelta import *
|
|
from itertools import groupby
|
|
from dateparser import parse
|
|
|
|
day = '[0-3]{0,1}[0-9]'
|
|
month = '[0,1]{0,1}[0-9]'
|
|
year = '\d{4}'
|
|
sep = '\s*[-/\.\s]\s*'
|
|
|
|
patterns = [
|
|
f"{day}{sep}{month}{sep}{year}",
|
|
f"{year}{sep}{month}{sep}{day}",
|
|
f"{day}\s+tháng\s+{month}",
|
|
f"{day}\s+tháng\s+{month}{sep}{year}",
|
|
f"{day}\s+tháng\s+{month}\s+năm\s+{year}",
|
|
f"{day}\s+tháng\s+{month}",
|
|
f"(?<=ngày)\s+{day}{sep}{month}",
|
|
f"(?<=ngày)\s+{day}{sep}{month}{sep}{year}",
|
|
f"(?<=sáng)\s+{day}{sep}{month}",
|
|
f"(?<=sáng)\s+{day}{sep}{month}{sep}{year}",
|
|
f"(?<=trưa)\s+{day}{sep}{month}",
|
|
f"(?<=trưa)\s+{day}{sep}{month}{sep}{year}",
|
|
f"(?<=chiều)\s+{day}{sep}{month}",
|
|
f"(?<=chiều)\s+{day}{sep}{month}{sep}{year}",
|
|
f"(?<=tối)\s+{day}{sep}{month}",
|
|
f"(?<=tối)\s+{day}{sep}{month}{sep}{year}"
|
|
f"(?<=đêm)\s+{day}{sep}{month}",
|
|
f"(?<=đêm)\s+{day}{sep}{month}{sep}{year}",
|
|
f"(?<=hôm)\s+{day}{sep}{month}",
|
|
f"(?<=hôm)\s+{day}{sep}{month}{sep}{year}",
|
|
f"{day}{sep}{month}[\s\.\,\)]"
|
|
]
|
|
|
|
|
|
def extract_pattern(text: str, patterns: List[str]):
|
|
detected = []
|
|
for pattern in patterns:
|
|
for match in re.finditer(pattern, text):
|
|
detected.append((match.start(), match.end()))
|
|
detected.sort()
|
|
output = []
|
|
curr = -1
|
|
for start, values in groupby(detected, key=operator.itemgetter(0)):
|
|
if start < curr:
|
|
continue
|
|
values = list(values)
|
|
values.sort(key=operator.itemgetter(1), reverse=True)
|
|
output.append(values[0])
|
|
curr = values[0][1]
|
|
return output
|
|
|
|
|
|
def detect_time(text: str, language: str = 'vi', base: Optional[datetime.datetime] = None):
|
|
text = text.lower()
|
|
detected_patterns = extract_pattern(text, patterns)
|
|
output = []
|
|
settings = {
|
|
'PREFER_DAY_OF_MONTH': 'first'
|
|
}
|
|
if base:
|
|
settings['RELATIVE_BASE'] = base
|
|
for start, end in detected_patterns:
|
|
segment = text[start:end]
|
|
segment = re.sub('\s+', ' ', segment).strip().lower()
|
|
candiate = parse(segment, languages=[language], settings=settings)
|
|
output.append((segment, candiate))
|
|
return output
|
|
|
|
|
|
def get_time_post(sentences, patterns, start_time=None, end_time=None):
|
|
dict_time_evs = {}
|
|
for i, sen in enumerate(sentences):
|
|
if sen.strip() != "":
|
|
time_ex = detect_time(sen, patterns)
|
|
for te in time_ex:
|
|
if te[1] is not None:
|
|
if start_time is None or end_time is None or (end_time > te[1].timestamp() > start_time):
|
|
if te not in dict_time_evs:
|
|
dict_time_evs[te] = []
|
|
dict_time_evs[te].append(i)
|
|
return dict_time_evs
|
|
|
|
|
|
if __name__ == '__main__':
|
|
print(detect_time("VietTimes – Ngoại trưởng Mỹ Antony Blinken ngày đã tuyên bố trong một cuộc họp qua"
|
|
"truyền hình với ngoại trưởng các nước ASEAN Mỹ bác bỏ các yêu sách “bất hợp pháp” của"
|
|
"Trung Quốc ở Biển Đông.", language="vi")) |