rime-ice/lua/number_translator.lua
Dvel 5c21df5cd9 feat!: 部件拆字反查、辅码 (#643)
BREAKING CHANGE: 部件拆字方案替换了两分方案

Co-authored-by: Mirtle <mirtle.cn@outlook.com>
2024-01-30 07:44:01 +08:00

130 lines
5.8 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 来源 https://github.com/yanhuacuo/98wubi-tables > http://98wb.ysepan.com/
-- 数字、金额大写
-- 触发前缀默认为 recognizer/patterns/number 的第 2 个字符,即 R
local function splitNumPart(str)
local part = {}
part.int, part.dot, part.dec = string.match(str, "^(%d*)(%.?)(%d*)")
return part
end
local function GetPreciseDecimal(nNum, n)
if type(nNum) ~= "number" then nNum =tonumber(nNum) end
n = n or 0;
n = math.floor(n)
if n < 0 then n = 0 end
local nDecimal = 10 ^ n
local nTemp = math.floor(nNum * nDecimal);
local nRet = nTemp / nDecimal;
return nRet;
end
local function decimal_func(str, posMap, valMap)
local dec
posMap = posMap or {[1]=""; [2]=""; [3]=""; [4]=""}
valMap = valMap or {[0]=""; ""; ""; "" ;""; ""; ""; ""; ""; ""}
if #str>4 then dec = string.sub(tostring(str), 1, 4) else dec =tostring(str) end
dec = string.gsub(dec, "0+$", "")
if dec == "" then return "" end
local result = ""
for pos =1, #dec do
local val = tonumber(string.sub(dec, pos, pos))
if val~=0 then result = result .. valMap[val] .. posMap[pos] else result = result .. valMap[val] end
end
result=result:gsub(valMap[0]..valMap[0] ,valMap[0])
return result:gsub(valMap[0]..valMap[0] ,valMap[0])
end
-- 把数字串按千分位四位数分割,进行转换为中文
local function formatNum(num,t)
local digitUnit,wordFigure
local result=""
num=tostring(num)
if tonumber(t) < 1 then digitUnit = {"", "", "",""} else digitUnit = {"","","",""} end
if tonumber(t) <1 then
wordFigure = {"","","","","","","","","",""}
else wordFigure = {"","","","","","","","","",""} end
if string.len(num)>4 or tonumber(num)==0 then return wordFigure[1] end
local lens=string.len(num)
for i=1,lens do
local n=wordFigure[tonumber(string.sub(num,-i,-i))+1]
if n~=wordFigure[1] then result=n .. digitUnit[i] .. result else result=n .. result end
end
result=result:gsub(wordFigure[1]..wordFigure[1] ,wordFigure[1])
result=result:gsub(wordFigure[1].."$","") result=result:gsub(wordFigure[1].."$","")
return result
end
-- 数值转换为中文
local function number2cnChar(num,flag,digitUnit,wordFigure) --flag=0中文小写反之为大写
local st,result
num=tostring(num) result=""
local num1,num2=math.modf(num)
if tonumber(num2)==0 then
if tonumber(flag) < 1 then
digitUnit = digitUnit or {[1]="";[2]="亿"} wordFigure = wordFigure or {[1]=""; [2]=""; [3]=""; [4]=""}
else
digitUnit = digitUnit or {[1]="";[2]="亿"} wordFigure = wordFigure or {[1]=""; [2]=""; [3]=""; [4]=""}
end
local lens=string.len(num1)
if lens<5 then result=formatNum(num1,flag) elseif lens<9 then result=formatNum(string.sub(num1,1,-5),flag) .. digitUnit[1].. formatNum(string.sub(num1,-4,-1),flag)
elseif lens<13 then result=formatNum(string.sub(num1,1,-9),flag) .. digitUnit[2] .. formatNum(string.sub(num1,-8,-5),flag) .. digitUnit[1] .. formatNum(string.sub(num1,-4,-1),flag) else result="" end
result=result:gsub("^" .. wordFigure[1],"") result=result:gsub(wordFigure[1] .. digitUnit[1],"") result=result:gsub(wordFigure[1] .. digitUnit[2],"")
result=result:gsub(wordFigure[1] .. wordFigure[1],wordFigure[1]) result=result:gsub(wordFigure[1] .. "$","")
if lens>4 then result=result:gsub("^"..wordFigure[2].. wordFigure[3],wordFigure[3]) end
if result~="" then result=result .. wordFigure[4] else result="数值超限!" end
else return "数值超限!" end
return result
end
local function number2zh(num,t)
local result,wordFigure
result=""
if tonumber(t) <1 then
wordFigure = {"","","","","","","","","",""}
else wordFigure = {"","","","","","","","","",""} end
if tostring(num)==nil then return "" end
for pos=1,string.len(num) do
result=result..wordFigure[tonumber(string.sub(num, pos, pos)+1)]
end
result=result:gsub(wordFigure[1] .. wordFigure[1],wordFigure[1])
return result:gsub(wordFigure[1] .. wordFigure[1],wordFigure[1])
end
local function number_translatorFunc(num)
local numberPart=splitNumPart(num)
local result={}
if numberPart.dot~="" then
table.insert(result,{number2cnChar(numberPart.int,0,{"", "亿"},{"","","",""})..number2zh(numberPart.dec,0),"〔数字小写〕"})
table.insert(result,{number2cnChar(numberPart.int,1,{"", ""},{"","","",""})..number2zh(numberPart.dec,1),"〔数字大写〕"})
else
table.insert(result,{number2cnChar(numberPart.int,0,{"", "亿"},{"","","",""}),"〔数字小写〕"})
table.insert(result,{number2cnChar(numberPart.int,1,{"", ""},{"","","",""}),"〔数字大写〕"})
end
table.insert(result,{number2cnChar(numberPart.int,0)..decimal_func(numberPart.dec,{[1]=""; [2]=""; [3]=""; [4]=""},{[0]=""; ""; ""; "" ;""; ""; ""; ""; ""; ""}),"〔金额小写〕"})
table.insert(result,{number2cnChar(numberPart.int,1)..decimal_func(numberPart.dec,{[1]=""; [2]=""; [3]=""; [4]=""},{[0]=""; ""; ""; "" ;""; ""; ""; ""; ""; ""}),"〔金额大写〕"})
return result
end
local function number_translator(input, seg, env)
-- 获取 recognizer/patterns/number 的第 2 个字符作为触发前缀
env.number_keyword = env.number_keyword or env.engine.schema.config:get_string('recognizer/patterns/number'):sub(2, 2)
local str, num, numberPart
if env.number_keyword ~= '' and input:sub(1, 1) == env.number_keyword then
str = string.gsub(input, "^(%a+)", "")
numberPart = number_translatorFunc(str)
if #numberPart > 0 then
for i = 1, #numberPart do
yield(Candidate(input, seg.start, seg._end, numberPart[i][1], numberPart[i][2]))
end
end
end
end
-- print(#number_translatorFunc(3355.433))
return number_translator