本篇設計一個Regular Expression的式子及Python程式,來理解使用者輸入的時間(不含日期),轉成標準的timestamp後,輸出給其它程式使用。
像這種時間、日期、數字等,有規則的字詞,用Regular Expression比利用機器學習還容易多,用機器學習還比較容易失敗。
下面的程式所用的Regular Expression式子有可能會接受錯誤的時間表示方式,畢竟想把所有可能的表示法塞在同一個式子,本來就不太可能,故若要改善,需要拆成多個式子來處理。
程式最下面的MAIN區塊,queryString是輸入的時間有關字句,getTime() 會把標準時間傳回來。
import re
import urllib
import pandas as pd
# constants for chinese_to_arabic
CN_NUM = {
'〇' : 0, '一' : 1, '二' : 2, '三' : 3, '四' : 4, '五' : 5, '六' : 6, '七' : 7, '八' : 8, '九' : 9, '零' : 0,
'壹' : 1, '贰' : 2, '叁' : 3, '肆' : 4, '伍' : 5, '陆' : 6, '柒' : 7, '捌' : 8, '玖' : 9, '貮' : 2, '两' : 2,
'0' : 0, '1' : 1, '2' : 2, '3' : 3, '4' : 4, '5' : 5, '6' : 6, '7' : 7, '8' : 8, '9' : 9
}
CN_UNIT = {
'十' : 10,
'拾' : 10,
'百' : 100,
'佰' : 100,
'千' : 1000,
'仟' : 1000,
'万' : 10000,
'萬' : 10000,
'亿' : 100000000,
'億' : 100000000,
'兆' : 1000000000000,
}
def chinese_to_arabic(cn):
unit = 0 # current
ldig = [] # digest
for cndig in reversed(cn):
if cndig in CN_UNIT:
unit = CN_UNIT.get(cndig)
if unit == 10000 or unit == 100000000:
ldig.append(unit)
unit = 1
else:
dig = CN_NUM.get(cndig)
if unit:
dig *= unit
unit = 0
ldig.append(dig)
if unit == 10:
ldig.append(10)
val, tmp = 0, 0
for x in reversed(ldig):
if x == 10000 or x == 100000000:
val += tmp * x
tmp = 0
else:
tmp += x
val += tmp
return val
def word2timestamp(test_str):
regex = r"(上午|下午|凌晨|中午|今夜|傍晚|午夜|半夜|夜間|大清早|早上|早晨|晚|晚上)?([零一二兩三四五六七八九十0123456789]+)[點|時|:]([零一二兩三四五六七八九十0123456789]*)[分|:]?([零一二兩三四五六七八九十0123456789]*)秒?\s?(am|pm|a.m|p.m|AM|PM|A.M|P.M)?"
match = re.search(regex, test_str, re.MULTILINE)
l = []
l.append(chinese_to_arabic(match.group(2)))
if (len(match.groups()) > 2):
l.append(chinese_to_arabic(match.group(3)))
if (len(match.groups()) > 3):
l.append(chinese_to_arabic(match.group(4)))
match.group(4)
if ((match.group(1) == "下午") & (l[0] <= 11) & (l[0] >= 1)):
l[0] += 12
if ((match.group(1) == "半夜") & (l[0] in [8, 9, 10, 11, 12])):
l[0] += 12
if ((match.group(1) == "今夜") & (l[0] in [5, 6, 7, 8, 9, 10, 11, 12])):
l[0] += 12
if ((match.group(1) == "傍晚") & (l[0] in [5, 6, 7, 8, 9, 10, 11, 12])):
l[0] += 12
if ((match.group(1) == "午夜") & (l[0] in [5, 6, 7, 8, 9, 10, 11, 12])):
l[0] += 12
if ((match.group(1) == "中午") & (l[0] in [1, 2, 3, 4, 5, 6])):
l[0] += 12
if ((match.group(1) == "夜間") & (l[0] in [6, 7, 8, 9, 10, 11, 12])):
l[0] += 12
if ((match.group(1) == "晚") & (l[0] in [6, 7, 8, 9, 10, 11, 12])):
l[0] += 12
if ((match.group(1) == "晚上") & (l[0] in [6, 7, 8, 9, 10, 11, 12])):
l[0] += 12
if l[0] == 24:
l[0] = 0
string = l[0]
for i in range(1, len(l)):
string = "%s:%d" % (string, l[i])
return string
def getTime(queryString):
url = 'http://morpheus.itri-nlp.tw:9801/v2/nlu/predict?' + urllib.parse.urlencode({'q': queryString})
f = urllib.request.urlopen(url)
timeInfo = pd.read_json(f.read())
return word2timestamp(timeInfo['response']['labels']['時間'][0]['rawEntity'])
if __name__ == '__main__':
queryString = '晚7點四十五分十二秒出發'
print(getTime(queryString)) # OUTPUT "19:45:12"
沒有留言:
張貼留言