lua里实现table的序列化和反序列化

   感谢原作者辛勤整理:Lua table的序列化和反序列化

--------------table转字符串(只取标准写法,以防止因系统的遍历次序导致ID乱序)

 

function sz_T2S(_t)  
    local szRet = "{"  
    function doT2S(_i, _v)  
        if "number" == type(_i) then  
            szRet = szRet .. "[" .. _i .. "] = "  
            if "number" == type(_v) then  
                szRet = szRet .. _v .. ","  
            elseif "string" == type(_v) then  
                szRet = szRet .. '"' .. _v .. '"' .. ","  
            elseif "table" == type(_v) then  
                szRet = szRet .. sz_T2S(_v) .. ","  
            else  
                szRet = szRet .. "nil,"  
            end  
        elseif "string" == type(_i) then  
            szRet = szRet .. '["' .. _i .. '"] = '  
            if "number" == type(_v) then  
                szRet = szRet .. _v .. ","  
            elseif "string" == type(_v) then  
                szRet = szRet .. '"' .. _v .. '"' .. ","  
            elseif "table" == type(_v) then  
                szRet = szRet .. sz_T2S(_v) .. ","  
            else  
                szRet = szRet .. "nil,"  
            end  
        end  
    end  
    table.foreach(_t, doT2S)  
    szRet = szRet .. "}"  
    return szRet  
end

字符串转table(反序列化,异常数据直接返回nil)

 

function t_S2T(_szText)  
    --栈  
    function stack_newStack()  
        local first = 1  
        local last = 0  
        local stack = {}  
        local m_public = {}  
        function m_public.pushBack(_tempObj)  
            last = last + 1  
            stack[last] = _tempObj  
        end  
        function m_public.temp_getBack()  
            if m_public.bool_isEmpty() then  
                return nil  
            else  
                local val = stack[last]  
                return val  
            end  
        end  
        function m_public.popBack()  
            stack[last] = nil  
            last = last - 1  
        end  
        function m_public.bool_isEmpty()  
            if first > last then  
                first = 1  
                last = 0  
                return true  
            else  
                return false  
            end  
        end  
        function m_public.clear()  
            while false == m_public.bool_isEmpty() do  
                stack.popFront()  
            end  
        end  
        return m_public  
    end  
    function getVal(_szVal)  
        local s, e = string.find(_szVal,'"',1,string.len(_szVal))  
        if nil ~= s and nil ~= e then  
            --return _szVal  
            return string.sub(_szVal,2,string.len(_szVal)-1)  
        else  
            return tonumber(_szVal)  
        end  
    end  
  
    local m_szText = _szText  
    local charTemp = string.sub(m_szText,1,1)  
    if "{" == charTemp then  
        m_szText = string.sub(m_szText,2,string.len(m_szText))  
    end  
    function doS2T()  
        local tRet = {}  
        local tTemp = nil  
        local stackOperator = stack_newStack()  
        local stackItem = stack_newStack()  
        local val = ""  
        while true do  
            local dLen = string.len(m_szText)  
            if dLen <= 0 then  
                break  
            end  
  
            charTemp = string.sub(m_szText,1,1)  
            if "[" == charTemp or "=" == charTemp then  
                stackOperator.pushBack(charTemp)  
                m_szText = string.sub(m_szText,2,dLen)  
            elseif '"' == charTemp then  
                local s, e = string.find(m_szText, '"', 2, dLen)  
                if nil ~= s and nil ~= e then  
                    val = val .. string.sub(m_szText,1,s)  
                    m_szText = string.sub(m_szText,s+1,dLen)  
                else  
                    return nil  
                end  
            elseif "]" == charTemp then  
                if "[" == stackOperator.temp_getBack() then  
                    stackOperator.popBack()  
                    stackItem.pushBack(val)  
                    val = ""  
                    m_szText = string.sub(m_szText,2,dLen)  
                else  
                    return nil  
                end  
            elseif "," == charTemp then  
                if "=" == stackOperator.temp_getBack() then  
                    stackOperator.popBack()  
                    local Item = stackItem.temp_getBack()  
                    Item = getVal(Item)  
                    stackItem.popBack()  
                    if nil ~= tTemp then  
                        tRet[Item] = tTemp  
                        tTemp = nil  
                    else  
                        tRet[Item] = getVal(val)  
                    end  
                    val = ""  
                    m_szText = string.sub(m_szText,2,dLen)  
                else  
                    return nil  
                end  
            elseif "{" == charTemp then  
                m_szText = string.sub(m_szText,2,string.len(m_szText))  
                local t = doS2T()  
                if nil ~= t then  
                    szText = sz_T2S(t)  
                    tTemp = t  
                    --val = val .. szText  
                else  
                    return nil  
                end  
            elseif "}" == charTemp then  
                m_szText = string.sub(m_szText,2,string.len(m_szText))  
                return tRet  
            elseif " " ~= charTemp then  
                val = val .. charTemp  
                m_szText = string.sub(m_szText,2,dLen)  
            else  
                m_szText = string.sub(m_szText,2,dLen)  
            end  
        end  
        return tRet  
    end  
    local t = doS2T()  
    return t  
end
其他方式: 

 

  1. function serialize(obj)  
  2.     local lua = ""  
  3.     local t = type(obj)  
  4.     if t == "number" then  
  5.         lua = lua .. obj  
  6.     elseif t == "boolean" then  
  7.         lua = lua .. tostring(obj)  
  8.     elseif t == "string" then  
  9.         lua = lua .. string.format("%q", obj)  
  10.     elseif t == "table" then  
  11.         lua = lua .. "{\n"  
  12.     for k, v in pairs(obj) do  
  13.         lua = lua .. "[" .. serialize(k) .. "]=" .. serialize(v) .. ",\n"  
  14.     end  
  15.     local metatable = getmetatable(obj)  
  16.         if metatable ~= nil and type(metatable.__index) == "table" then  
  17.         for k, v in pairs(metatable.__index) do  
  18.             lua = lua .. "[" .. serialize(k) .. "]=" .. serialize(v) .. ",\n"  
  19.         end  
  20.     end  
  21.         lua = lua .. "}"  
  22.     elseif t == "nil" then  
  23.         return nil  
  24.     else  
  25.         error("can not serialize a " .. t .. " type.")  
  26.     end  
  27.     return lua  
  28. end 
  29. ----反序列化
  1. function serialize(obj)  
  2.     local lua = ""  
  3.     local t = type(obj)  
  4.     if t == "number" then  
  5.         lua = lua .. obj  
  6.     elseif t == "boolean" then  
  7.         lua = lua .. tostring(obj)  
  8.     elseif t == "string" then  
  9.         lua = lua .. string.format("%q", obj)  
  10.     elseif t == "table" then  
  11.         lua = lua .. "{\n"  
  12.     for k, v in pairs(obj) do  
  13.         lua = lua .. "[" .. serialize(k) .. "]=" .. serialize(v) .. ",\n"  
  14.     end  
  15.     local metatable = getmetatable(obj)  
  16.         if metatable ~= nil and type(metatable.__index) == "table" then  
  17.         for k, v in pairs(metatable.__index) do  
  18.             lua = lua .. "[" .. serialize(k) .. "]=" .. serialize(v) .. ",\n"  
  19.         end  
  20.     end  
  21.         lua = lua .. "}"  
  22.     elseif t == "nil" then  
  23.         return nil  
  24.     else  
  25.         error("can not serialize a " .. t .. " type.")  
  26.     end  
  27.     return lua  
  28. end 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值