模块:ChineseNumToArabicNum

可在模块:ChineseNumToArabicNum/doc创建此模块的帮助文档

p={}

-- 定义常量
local cnArr = {'零','一','二','三','四','五','六','七','八','九'}
local chArr = {'零','十','百','千','万','亿'}
local allChineseNum = "零一二三四五六七八九十百千万亿"
local allChineseNumArr = {'零','一','二','三','四','五','六','七','八','九','十','百','千','万','亿'}
local allArabicNum = "0123456789"
local num1 = "一二三四五六七八九"
local num2 = "十百千万亿"
local zero = "零"

function utf8len(str)
    local len = 0
    local i = 1
    while i <= #str do
        local byte1 = string.byte(str, i)
        if byte1 >= 0xC0 and byte1 <= 0xDF then
            i = i + 2
        elseif byte1 >= 0xE0 and byte1 <= 0xEF then
            i = i + 3
        elseif byte1 >= 0xF0 and byte1 <= 0xF7 then
            i = i + 4
        else
            i = i + 1
        end
        len = len + 1
    end
    return len
end
p.utf8len=utf8len

function getUTF8Char(str, index)
    local len = 0
    local i = 1
    while i <= #str do
        local byte1 = string.byte(str, i)
        if byte1 >= 0xC0 and byte1 <= 0xDF then
            if len == index then
                return string.sub(str, i, i + 1)
            end
            i = i + 2
        elseif byte1 >= 0xE0 and byte1 <= 0xEF then
            if len == index then
                return string.sub(str, i, i + 2)
            end
            i = i + 3
        elseif byte1 >= 0xF0 and byte1 <= 0xF7 then
            if len == index then
                return string.sub(str, i, i + 3)
            end
            i = i + 4
        else
            if len == index then
                return string.sub(str, i, i)
            end
            i = i + 1
        end
        len = len + 1
    end
    return nil
end
p.getUTF8Char=getUTF8Char

function isChineseNumChar(c)
	for j = 1, #allChineseNumArr do
        if c == allChineseNumArr[j] then
        	--mw.log(c)
        	return true
        end
	end

	return false
end

function getFirstChineseNum(chineseStr)
	local hasNum = false
	local chineseNum=""
    for i = 0, utf8len(chineseStr)-1 do
        local c = getUTF8Char(chineseStr, i)
        --mw.log(c)
        if isChineseNumChar(c) then
        	--mw.log(c)
        	hasNum=true
        	chineseNum = chineseNum..c
        elseif hasNum then
        	break
        end

    end
    return chineseNum
end
p.getFirstChineseNum=getFirstChineseNum

-- 将汉字中的数字转换为阿拉伯数字,转换纯中文数字
function chineseNumToArabicNum(chineseNum)
    local result = 0
    local temp = 1 -- 存放一个单位的数字如:十万
    local count = 0 -- 判断是否有 chArr
    local lenChineseNum=utf8len(chineseNum)
    for i = 0, lenChineseNum-1 do
        local b = true -- 判断是否是 chArr
        local c = getUTF8Char(chineseNum, i)
        --mw.log(c)
        for j = 1, #cnArr do
            if c == cnArr[j] then
            	--mw.log("c == cnArr[j] "..cnArr[j])
                if count ~= 0 then -- 添加下一个单位之前,先把上一个单位值添加到结果中
                    result = result + temp
                    temp = 1
                    count = 0
                end
                -- 下标,就是对应的值
                temp = j-1
                b = false
                break
            end
        end
        if b then -- 单位{'十','百','千','万','亿'}
            for j = 1, #chArr do
                if c == chArr[j] then
                	--mw.log("c == chArr[j] "..chArr[j])
                    if j == 1+1 then
                        temp = temp * 10
                    elseif j == 2+1 then
                        temp = temp * 100
                    elseif j == 3+1 then
                        temp = temp * 1000
                    elseif j == 4+1 then
                        temp = temp * 10000
                    elseif j == 5+1 then
                        temp = temp * 100000000
                    end
                    count = count + 1
                end
            end
        end
        --mw.log("i "..i)
        --mw.log("lenChineseNum "..lenChineseNum)
        if i >= lenChineseNum-1 then -- 遍历到最后一个字符
            result = result + temp
        end
    end
    return result
end
p.chineseNumToArabicNum=chineseNumToArabicNum

--[[
-- 将字符串中的中文数字转换阿拉伯数字,其它非数字汉字不替换
function chineseNumToArabicNumTwo(chineseNum)
    local resultStr = ""
    local tempresult = 0
    local temp = 1 -- 存放一个单位的数字如:十万
    local count = 0 -- 判断是否有单位
    -- 重新将 temp, count, tempresult 设置为初始值
    local setInitial = false
    -- 以十百千万亿结束的在最后加
    local isAdd = false
    local num1flag = false
    local num2flag = false
    for i = 1, #chineseNum do
        if setInitial then
            tempresult = 0
            temp = 1
            count = 0
            setInitial = false
        end
        local b = true -- 判断是否是 chArr
        local c = string.sub(chineseNum, i, i)
        if string.find(allChineseNum, c) then
            if i < #chineseNum and string.find(num1, c) and string.find(num1, string.sub(chineseNum, i + 1, i + 1)) then
                num1flag = true
            end
            for j = 1, #cnArr do
                if c == cnArr[j] then
                    if count ~= 0 then -- 添加下一个单位之前,先把上一个单位值添加到结果中
                        tempresult = tempresult + temp
                        temp = 1
                        count = 0
                    end
                    if not isAdd and (i == #chineseNum or string.find(allChineseNum, string.sub(chineseNum, i + 1, i + 1)) == nil) then
                        tempresult = tempresult + j
                        setInitial = true
                        resultStr = resultStr.. tempresult
                        isAdd = true
                    end
                    -- 下标+1,就是对应的值
                    temp = j
                    b = false
                    break
                end
            end
            if num1flag then
                resultStr = resultStr.. temp
                num1flag = false
                setInitial = true
                goto continue
            end
            local test = (i < #chineseNum and string.find(zero, string.sub(chineseNum, i + 1, i + 1)) ~= nil) or
                    (i > 0 and string.find(zero, string.sub(chineseNum, i - 1, i - 1)) ~= nil)
            if i < #chineseNum and string.find(zero, c) and test then
                num2flag = true
            end
            if b then -- 单位{'十','百','千','万','亿'}
                for j = 1, #chArr do
                    if c == chArr[j] then
                        if j == 1 then
                            temp = temp * 10
                        elseif j == 2 then
                            temp = temp * 100
                        elseif j == 3 then
                            temp = temp * 1000
                        elseif j == 4 then
                            temp = temp * 10000
                        elseif j == 5 then
                            temp = temp * 100000000
                        end
                        count = count + 1
                    end
                end
            end
            if num2flag then
                resultStr = resultStr.. temp
                num2flag = false
                setInitial = true
                goto continue
            end
            if not isAdd and (i == #chineseNum or string.find(allChineseNum, string.sub(chineseNum, i + 1, i + 1)) == nil) then
                tempresult = tempresult + temp
                setInitial = true
                resultStr = resultStr.. tempresult
                isAdd = true
            end
        else
            isAdd = false
            resultStr = resultStr.. c
        end
        ::continue::
    end
    return resultStr
end

-- 将数字转换为中文数字,这里只写到了万
function arabicNumToChineseNum(intInput)
    local si = tostring(intInput)
    local sd = ""
    if #si == 1 then
        if intInput == 0 then
            return sd
        end
        sd = sd.. cnArr[intInput + 1]
        return sd
    elseif #si == 2 then
        if string.sub(si, 1, 1) == "1" then
            sd = sd.. "十"
            if intInput % 10 == 0 then
                return sd
            end
        else
            sd = sd.. cnArr[(intInput / 10) + 1].. "十"
        end
        sd = sd.. arabicNumToChineseNum(intInput % 10)
    elseif #si == 3 then
        sd = sd.. cnArr[(intInput / 100) + 1].. "百"
        if #tostring(intInput % 100) < 2 then
            if intInput % 100 == 0 then
                return sd
            end
            sd = sd.. "零"
        end
        sd = sd.. arabicNumToChineseNum(intInput % 100)
    elseif #si == 4 then
        sd = sd.. cnArr[(intInput / 1000) + 1].. "千"
        if #tostring(intInput % 1000) < 3 then
            if intInput % 1000 == 0 then
                return sd
            end
            sd = sd.. "零"
        end
        sd = sd.. arabicNumToChineseNum(intInput % 1000)
    elseif #si == 5 then
        sd = sd.. cnArr[(intInput / 10000) + 1].. "万"
        if #tostring(intInput % 10000) < 4 then
            if intInput % 10000 == 0 then
                return sd
            end
            sd = sd.. "零"
        end
        sd = sd.. arabicNumToChineseNum(intInput % 10000)
    end
    return sd
end

-- 判断传入的字符串是否全是汉字数字
function isChineseNum(chineseStr)
    for c in string.gmatch(chineseStr, ".") do
        if string.find(allChineseNum, c) == nil then
            return false
        end
    end
    return true
end

-- 判断数字字符串是否是整数字符串
function isNum(str)
    local reg = "[0-9]+"
    return string.match(str, reg) ~= nil
end

]]

function p.get(frame)
	local args = (frame == mw.getCurrentFrame() and frame.args) or frame
	chineseNum=args[1]
	
	chineseNum=getFirstChineseNum(chineseNum)
	if chineseNum=='' then
		return 0
	end
	
	rtn=chineseNumToArabicNum(chineseNum)
	return rtn
end

function p.mulTen(frame)
	local args = (frame == mw.getCurrentFrame() and frame.args) or frame
	chineseNum=args[1]
	
	chineseNum=getFirstChineseNum(chineseNum)
	if chineseNum=='' then
		return -1000
	end
	
	rtn=chineseNumToArabicNum(chineseNum)*10
	return rtn
end


return p