Lua里实现将table转成字符串(序列化)和将字符串转换回table(反
发布时间:2020-12-14 22:02:24 所属栏目:大数据 来源:网络整理
导读:转载自: http://www.voidcn.com/article/p-hhamkjgx-bcy.html --[[ file name : table序列化和反序列化的问题.lua author : Clark/陈泽丹 created : 2011-12-22 备注: 支持table的递归结构,但数据类型不支持function属性(因为function只是记录地址,在不同
转载自: http://www.voidcn.com/article/p-hhamkjgx-bcy.html--[[ file name : table序列化和反序列化的问题.lua author : Clark/陈泽丹 created : 2011-12-22 备注: 支持table的递归结构,但数据类型不支持function属性(因为function只是记录地址,在不同机器上序列化和反序列化后的地址相同没什么意义) 后记: 郁闷, 写完到网上一搜, 才发现原来Lua有提供一些现成的函数可用来做序列化和反序列化操作。。。 其中loadstring可以执行字符串。 通过 lua = "return " .. lua local func = loadstring(lua) 即实现了反序列化。。。 --]]
----------- 个人编写 -----------------
--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 .. ","
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)
if "{" == charTemp then
m_szText = string.sub(m_szText,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)
if "[" == charTemp or "=" == charTemp then
stackOperator.pushBack(charTemp)
m_szText = string.sub(m_szText,dLen)
elseif '"' == charTemp then
local s,e = string.find(m_szText,dLen)
if nil ~= s and nil ~= e then
val = val .. string.sub(m_szText,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,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,dLen)
else
return nil
end
elseif "{" == charTemp then
m_szText = string.sub(m_szText,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,string.len(m_szText))
return tRet
elseif " " ~= charTemp then
val = val .. charTemp
m_szText = string.sub(m_szText,dLen)
else
m_szText = string.sub(m_szText,dLen)
end
end
return tRet
end
local t = doS2T()
return t
end
--[[ t = {1,2,3,"sdf",a = "df",qe = 3,{7},qq = {{2,a={}}},} t.f = {1,3} t.m = {3,4,5} szT = sz_T2S(t) print(szT) print("-----------") tq = t_S2T(szT) szT = sz_T2S(tq) print(szT) --]]
-------- 网上资料 -------------------
function serialize(obj)
local lua = ""
local t = type(obj)
if t == "number" then
lua = lua .. obj
elseif t == "boolean" then
lua = lua .. tostring(obj)
elseif t == "string" then
lua = lua .. string.format("%q",obj)
elseif t == "table" then
lua = lua .. "{n"
for k,v in pairs(obj) do
lua = lua .. "[" .. serialize(k) .. "]=" .. serialize(v) .. ",n"
end
local metatable = getmetatable(obj)
if metatable ~= nil and type(metatable.__index) == "table" then
for k,v in pairs(metatable.__index) do
lua = lua .. "[" .. serialize(k) .. "]=" .. serialize(v) .. ",n"
end
end
lua = lua .. "}"
elseif t == "nil" then
return nil
else
error("can not serialize a " .. t .. " type.")
end
return lua
end
function unserialize(lua)
local t = type(lua)
if t == "nil" or lua == "" then
return nil
elseif t == "number" or t == "string" or t == "boolean" then
lua = tostring(lua)
else
error("can not unserialize a " .. t .. " type.")
end
lua = "return " .. lua
local func = loadstring(lua)
if func == nil then
return nil
end
return func()
end
data = {["a"] = "a",["b"] = "b",[1] = 1,[2] = 2,["t"] = {1,3}}
local sz = serialize(data)
print(sz)
print("---------")
print(serialize(unserialize(sz)))
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |